diff options
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 55e2a92476..0543b0adc6 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1763,11 +1763,27 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, OverloadedFunctionDecl::function_iterator MatchedDecl; if (!getLangOptions().CPlusPlus && - AllowOverloadingOfFunction(PrevDecl, Context)) + AllowOverloadingOfFunction(PrevDecl, Context)) { OverloadableAttrRequired = true; - if (!AllowOverloadingOfFunction(PrevDecl, Context) || - !IsOverload(NewFD, PrevDecl, MatchedDecl)) { + // Functions marked "overloadable" must have a prototype (that + // we can't get through declaration merging). + if (!R->getAsFunctionTypeProto()) { + Diag(NewFD->getLocation(), diag::err_attribute_overloadable_no_prototype) + << NewFD; + InvalidDecl = true; + Redeclaration = true; + + // Turn this into a variadic function with no parameters. + R = Context.getFunctionType(R->getAsFunctionType()->getResultType(), + 0, 0, true, 0); + NewFD->setType(R); + } + } + + if (PrevDecl && + (!AllowOverloadingOfFunction(PrevDecl, Context) || + !IsOverload(NewFD, PrevDecl, MatchedDecl))) { Redeclaration = true; Decl *OldDecl = PrevDecl; |