From 32825354fedd3aa106c1b914680f011a78e9b089 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Fri, 20 Jan 2017 12:05:52 +0100 Subject: [PATCH 1/2] Avoid checking if a function uses itself as function pointer Fixes #206 The sample code from the issue provided a smart way to cheat the dumb FP parser. In fact, the & is referred to the return type (correct) but the comparator doesn't know about semantics and simply prepends the ampersand before searching for the match. So the code matches itself, which makes absolutely no sense. Avoiding this occurrence fixes the issue, however the entire code for prototype line insertion should be refactored in a saner way (see #180 and #191 for another problem) --- .../builder/ctags/ctags_to_prototypes.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/arduino.cc/builder/ctags/ctags_to_prototypes.go b/src/arduino.cc/builder/ctags/ctags_to_prototypes.go index 459174d8..d4138416 100644 --- a/src/arduino.cc/builder/ctags/ctags_to_prototypes.go +++ b/src/arduino.cc/builder/ctags/ctags_to_prototypes.go @@ -56,32 +56,32 @@ func (p *CTagsParser) findLineWhereToInsertPrototypes() int { } func (p *CTagsParser) firstFunctionPointerUsedAsArgument() int { - functionNames := p.collectFunctionNames() + functionTags := p.collectFunctions() for _, tag := range p.tags { - if functionNameUsedAsFunctionPointerIn(tag, functionNames) { + if functionNameUsedAsFunctionPointerIn(tag, functionTags) { return tag.Line } } return -1 } -func functionNameUsedAsFunctionPointerIn(tag *types.CTag, functionNames []string) bool { - for _, functionName := range functionNames { - if strings.Index(tag.Code, "&"+functionName) != -1 { +func functionNameUsedAsFunctionPointerIn(tag *types.CTag, functionTags []*types.CTag) bool { + for _, functionTag := range functionTags { + if tag.Line != functionTag.Line && strings.Index(tag.Code, "&"+functionTag.FunctionName) != -1 { return true } } return false } -func (p *CTagsParser) collectFunctionNames() []string { - names := []string{} +func (p *CTagsParser) collectFunctions() []*types.CTag { + functionTags := []*types.CTag{} for _, tag := range p.tags { if tag.Kind == KIND_FUNCTION { - names = append(names, tag.FunctionName) + functionTags = append(functionTags, tag) } } - return names + return functionTags } func (p *CTagsParser) firstFunctionAtLine() int { From 9165d1bf3849eefbca96f6bf4d70a26f0ec7d9a4 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Fri, 20 Jan 2017 12:51:24 +0100 Subject: [PATCH 2/2] Add test for fake function pointers --- .../sketch_with_fake_function_pointer.ino | 19 +++++++++++++++++++ .../try_build_of_problematic_sketch_test.go | 4 ++++ 2 files changed, 23 insertions(+) create mode 100644 src/arduino.cc/builder/test/sketch_with_fake_function_pointer/sketch_with_fake_function_pointer.ino diff --git a/src/arduino.cc/builder/test/sketch_with_fake_function_pointer/sketch_with_fake_function_pointer.ino b/src/arduino.cc/builder/test/sketch_with_fake_function_pointer/sketch_with_fake_function_pointer.ino new file mode 100644 index 00000000..eb83500c --- /dev/null +++ b/src/arduino.cc/builder/test/sketch_with_fake_function_pointer/sketch_with_fake_function_pointer.ino @@ -0,0 +1,19 @@ +template< uint16_t nBuffSize > + class Foo{ + public: + + template< uint16_t N > + Foo &operator +=( const Foo &ref ){ + //... + return *this; + } +}; + +Foo<64> a; +Foo<32> b; + +void setup(){ + a += b; +} + +void loop(){} diff --git a/src/arduino.cc/builder/test/try_build_of_problematic_sketch_test.go b/src/arduino.cc/builder/test/try_build_of_problematic_sketch_test.go index 5cbbf5cf..160c81c5 100644 --- a/src/arduino.cc/builder/test/try_build_of_problematic_sketch_test.go +++ b/src/arduino.cc/builder/test/try_build_of_problematic_sketch_test.go @@ -205,6 +205,10 @@ func TestTryBuild039(t *testing.T) { tryBuildWithContext(t, ctx, "sketch12", "sketch12.ino") } +func TestTryBuild040(t *testing.T) { + tryBuild(t, "sketch_with_fake_function_pointer", "sketch_with_fake_function_pointer.ino") +} + func makeDefaultContext(t *testing.T) *types.Context { DownloadCoresAndToolsAndLibraries(t)