amusman created this revision. amusman added reviewers: rsmith, aaron.ballman, ABataev. amusman added a subscriber: cfe-commits.
In the following example, we have a declaration of weakfoo before #pragma weak. extern void weakfoo(); void localfoo() { } #pragma weak weakfoo=localfoo There are two decls for weakfoo, this leads to assertion failure later (during search a decl for a call to weakfoo): lib/Sema/SemaOverload.cpp:5583: void clang::Sema::AddOverloadCandidate(clang::FunctionDecl*, clang::DeclAccessPair, llvm::ArrayRef<clang::Expr*>, clang::OverloadCandidateSet&, bool, bool, bool): Assertion `Proto && "Functions without a prototype cannot be overloaded"' failed. I suggest to call CheckFunctionDeclaration so that 2 decls for the weakfoo are merged. http://reviews.llvm.org/D13048 Files: lib/Sema/SemaDeclAttr.cpp test/CodeGen/pragma-weak.c test/Sema/pragma-weak.c Index: lib/Sema/SemaDeclAttr.cpp =================================================================== --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5198,17 +5198,22 @@ assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); NamedDecl *NewD = nullptr; if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { - FunctionDecl *NewFD; - // FIXME: Missing call to CheckFunctionDeclaration(). // FIXME: Mangling? // FIXME: Is the qualifier info correct? // FIXME: Is the DeclContext correct? - NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), - Loc, Loc, DeclarationName(II), - FD->getType(), FD->getTypeSourceInfo(), - SC_None, false/*isInlineSpecified*/, - FD->hasPrototype(), - false/*isConstexprSpecified*/); + + LookupResult Previous(*this, II, Loc, LookupOrdinaryName); + LookupParsedName(Previous, TUScope, nullptr, true); + + auto NewFD = FunctionDecl::Create( + FD->getASTContext(), FD->getDeclContext(), Loc, Loc, + DeclarationName(II), FD->getType(), FD->getTypeSourceInfo(), SC_None, + false /*isInlineSpecified*/, FD->hasPrototype(), + false /*isConstexprSpecified*/); + + CheckFunctionDeclaration(TUScope, NewFD, Previous, + false /*IsExplicitSpecialization*/); + NewD = NewFD; if (FD->getQualifier()) Index: test/CodeGen/pragma-weak.c =================================================================== --- test/CodeGen/pragma-weak.c +++ test/CodeGen/pragma-weak.c @@ -17,6 +17,7 @@ // CHECK-DAG: @mix2 = weak alias void (), void ()* @__mix2 // CHECK-DAG: @a1 = weak alias void (), void ()* @__a1 // CHECK-DAG: @xxx = weak alias void (), void ()* @__xxx +// CHECK-DAG: @weakfoo = weak alias void {{.*}} @localfoo @@ -173,6 +174,14 @@ // CHECK: declare extern_weak i32 @PR16705b() // CHECK: declare extern_weak i32 @PR16705c() +// In this test case, we have a declaration of weakfoo before #pragma weak. +// Test that 2 decls for the weakfoo are merged. +extern void weakfoo(); +void localfoo() { } +#pragma weak weakfoo=localfoo +extern void externmain() { return weakfoo(); } +// CHECK-LABEL: define void @externmain() +// CHECK: call{{.*}}@weakfoo ///////////// TODO: stuff that still doesn't work Index: test/Sema/pragma-weak.c =================================================================== --- test/Sema/pragma-weak.c +++ test/Sema/pragma-weak.c @@ -9,3 +9,9 @@ #pragma weak a3 = __a3 // expected-note {{previous definition}} void a3(void) __attribute((alias("__a3"))); // expected-error {{redefinition of 'a3'}} void __a3(void) {} + +extern void weak2foo(int); // expected-note {{previous declaration is here}} expected-note {{'weak2foo' declared here}} +void local2foo(double d1, double d2) { } +#pragma weak weak2foo=local2foo // expected-error {{conflicting types for 'weak2foo'}} +extern void extern2main() { return weak2foo(); } // expected-error {{too few arguments to function call, expected 1, have 0}} +
Index: lib/Sema/SemaDeclAttr.cpp =================================================================== --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5198,17 +5198,22 @@ assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); NamedDecl *NewD = nullptr; if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { - FunctionDecl *NewFD; - // FIXME: Missing call to CheckFunctionDeclaration(). // FIXME: Mangling? // FIXME: Is the qualifier info correct? // FIXME: Is the DeclContext correct? - NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), - Loc, Loc, DeclarationName(II), - FD->getType(), FD->getTypeSourceInfo(), - SC_None, false/*isInlineSpecified*/, - FD->hasPrototype(), - false/*isConstexprSpecified*/); + + LookupResult Previous(*this, II, Loc, LookupOrdinaryName); + LookupParsedName(Previous, TUScope, nullptr, true); + + auto NewFD = FunctionDecl::Create( + FD->getASTContext(), FD->getDeclContext(), Loc, Loc, + DeclarationName(II), FD->getType(), FD->getTypeSourceInfo(), SC_None, + false /*isInlineSpecified*/, FD->hasPrototype(), + false /*isConstexprSpecified*/); + + CheckFunctionDeclaration(TUScope, NewFD, Previous, + false /*IsExplicitSpecialization*/); + NewD = NewFD; if (FD->getQualifier()) Index: test/CodeGen/pragma-weak.c =================================================================== --- test/CodeGen/pragma-weak.c +++ test/CodeGen/pragma-weak.c @@ -17,6 +17,7 @@ // CHECK-DAG: @mix2 = weak alias void (), void ()* @__mix2 // CHECK-DAG: @a1 = weak alias void (), void ()* @__a1 // CHECK-DAG: @xxx = weak alias void (), void ()* @__xxx +// CHECK-DAG: @weakfoo = weak alias void {{.*}} @localfoo @@ -173,6 +174,14 @@ // CHECK: declare extern_weak i32 @PR16705b() // CHECK: declare extern_weak i32 @PR16705c() +// In this test case, we have a declaration of weakfoo before #pragma weak. +// Test that 2 decls for the weakfoo are merged. +extern void weakfoo(); +void localfoo() { } +#pragma weak weakfoo=localfoo +extern void externmain() { return weakfoo(); } +// CHECK-LABEL: define void @externmain() +// CHECK: call{{.*}}@weakfoo ///////////// TODO: stuff that still doesn't work Index: test/Sema/pragma-weak.c =================================================================== --- test/Sema/pragma-weak.c +++ test/Sema/pragma-weak.c @@ -9,3 +9,9 @@ #pragma weak a3 = __a3 // expected-note {{previous definition}} void a3(void) __attribute((alias("__a3"))); // expected-error {{redefinition of 'a3'}} void __a3(void) {} + +extern void weak2foo(int); // expected-note {{previous declaration is here}} expected-note {{'weak2foo' declared here}} +void local2foo(double d1, double d2) { } +#pragma weak weak2foo=local2foo // expected-error {{conflicting types for 'weak2foo'}} +extern void extern2main() { return weak2foo(); } // expected-error {{too few arguments to function call, expected 1, have 0}} +
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits