diff options
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 22 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 12 |
2 files changed, 29 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 55e2a924762..0543b0adc67 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/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; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index c0b61bf8d7c..48f338e475d 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2032,13 +2032,21 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, // Make the call expr early, before semantic checks. This guarantees cleanup // of arguments and function on error. - // FIXME: Except that llvm::OwningPtr uses delete, when it really must be - // Destroy(), or nothing gets cleaned up. ExprOwningPtr<CallExpr> TheCall(this, new (Context) CallExpr(Context, Fn, Args, NumArgs, Context.BoolTy, RParenLoc)); + // Check for a call to a (FIXME: deleted) or unavailable function. + if (FDecl && FDecl->getAttr<UnavailableAttr>()) { + Diag(Fn->getSourceRange().getBegin(), diag::err_call_deleted_function) + << FDecl->getAttr<UnavailableAttr>() << FDecl->getDeclName() + << Fn->getSourceRange(); + Diag(FDecl->getLocation(), diag::note_deleted_function_here) + << FDecl->getAttr<UnavailableAttr>(); + return ExprError(); + } + const FunctionType *FuncT; if (!Fn->getType()->isBlockPointerType()) { // C99 6.5.2.2p1 - "The expression that denotes the called function shall |

