summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp22
-rw-r--r--clang/lib/Sema/SemaExpr.cpp12
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
OpenPOWER on IntegriCloud