From: Alp Toker Date: Sun, 20 Oct 2013 18:48:56 +0000 (+0000) Subject: Fix crash in cleanup attr handling X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8b407727aef487051835440deb641e60f7a743f8;p=clang Fix crash in cleanup attr handling ResolveSingleFunctionTemplateSpecialization() returns 0 and doesn't emit diags unless the expression has template-ids, so we must null check the result. Also add a better diag noting which overloads are causing the problem. Reviewed by Aaron Ballman. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@193055 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 55c4e9d57b..d582ad5ad7 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2365,7 +2365,7 @@ def warn_cleanup_ext : Warning< "than a simple identifier">, InGroup; def err_attribute_cleanup_arg_not_function : Error< - "'cleanup' argument %select{|%1 }0is not a function">; + "'cleanup' argument %select{|%1 |%1 }0is not a %select{||single }0function">; def err_attribute_cleanup_func_must_take_one_arg : Error< "'cleanup' function %0 must take 1 parameter">; def err_attribute_cleanup_func_arg_incompatible_type : Error< diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 3eabf87624..a71d3c0d7b 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -2899,10 +2899,15 @@ static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) { } else if (UnresolvedLookupExpr *ULE = dyn_cast(E)) { if (ULE->hasExplicitTemplateArgs()) S.Diag(Loc, diag::warn_cleanup_ext); - - // This will diagnose the case where the function cannot be found. FD = S.ResolveSingleFunctionTemplateSpecialization(ULE, true); NI = ULE->getNameInfo(); + if (!FD) { + S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 2 + << NI.getName(); + if (ULE->getType() == S.Context.OverloadTy) + S.NoteAllOverloadCandidates(ULE); + return; + } } else { S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 0; return; diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 6dbb7b6cc5..20cfb00584 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -9672,6 +9672,9 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *AddressOfExpr, /// template, where that template-id refers to a single template whose template /// arguments are either provided by the template-id or have defaults, /// as described in C++0x [temp.arg.explicit]p3. +/// +/// If no template-ids are found, no diagnostics are emitted and NULL is +/// returned. FunctionDecl * Sema::ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl, bool Complain, diff --git a/test/SemaCXX/attr-cleanup.cpp b/test/SemaCXX/attr-cleanup.cpp index b6c58533ac..764df997de 100644 --- a/test/SemaCXX/attr-cleanup.cpp +++ b/test/SemaCXX/attr-cleanup.cpp @@ -19,3 +19,11 @@ class D : public C { int v1 __attribute__((cleanup(c2))); // expected-error {{'c2' is a private member of 'C'}} } }; + +namespace E { + void c3(int *a) {} // expected-note {{candidate function}} + void c3() {} // expected-note {{candidate function}} + void t3() { + int v1 __attribute__((cleanup(c3))); // expected-error {{'c3' is not a single function}} + } +}