From: Anders Carlsson Date: Sat, 7 Feb 2009 23:16:50 +0000 (+0000) Subject: Improve Sema of the cleanup attribute somewhat. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=89941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083;p=clang Improve Sema of the cleanup attribute somewhat. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64047 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.def b/include/clang/Basic/DiagnosticSemaKinds.def index a18ed966f3..539b659d63 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.def +++ b/include/clang/Basic/DiagnosticSemaKinds.def @@ -385,8 +385,10 @@ DIAG(err_attribute_cleanup_arg_not_found, ERROR, "'cleanup' argument %0 not found") DIAG(err_attribute_cleanup_arg_not_function, ERROR, "'cleanup' argument %0 is not a function") -DIAG(err_attribute_cleanup_arg_must_take_one_arg, ERROR, +DIAG(err_attribute_cleanup_func_must_take_one_arg, ERROR, "'cleanup' function %0 must take 1 parameter") +DIAG(err_attribute_cleanup_func_arg_incompatible_type, ERROR, + "'cleanup' function %0 parameter has type %1, expected type %2") // Clang-Specific Attributes DIAG(err_attribute_iboutlet_non_ivar, ERROR, diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 231efc7563..2a6da06f71 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -847,6 +847,10 @@ static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { } static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { + // Match gcc which ignores cleanup attrs when compiling C++. + if (S.getLangOptions().CPlusPlus) + return; + if (!Attr.getParameterName()) { S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; return; @@ -868,26 +872,35 @@ static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { NamedDecl *CleanupDecl = S.LookupName(S.TUScope, Attr.getParameterName(), Sema::LookupOrdinaryName); if (!CleanupDecl) { - S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) << + S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) << Attr.getParameterName(); return; } FunctionDecl *FD = dyn_cast(CleanupDecl); if (!FD) { - S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) << + S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) << Attr.getParameterName(); return; } - // FIXME: This needs to work with C++ overloading. - // FIXME: This should verify that the function type is compatible if (FD->getNumParams() != 1) { - S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_must_take_one_arg)<< + S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) << Attr.getParameterName(); return; } + // We're currently more strict than GCC about what function types we accept. + // If this ever proves to be a problem it should be easy to fix. + QualType Ty = S.Context.getPointerType(VD->getType()); + QualType ParamTy = FD->getParamDecl(0)->getType(); + if (Ty != ParamTy) { + S.Diag(Attr.getLoc(), + diag::err_attribute_cleanup_func_arg_incompatible_type) << + Attr.getParameterName() << ParamTy << Ty; + return; + } + d->addAttr(new CleanupAttr(FD)); } diff --git a/test/Sema/attr-cleanup.c b/test/Sema/attr-cleanup.c index c58d17b7ef..e5dd3a26d8 100644 --- a/test/Sema/attr-cleanup.c +++ b/test/Sema/attr-cleanup.c @@ -24,8 +24,10 @@ struct s { }; void c2(); +void c3(struct s a); void t2() { int v1 __attribute__((cleanup(c2))); // expected-error {{'cleanup' function 'c2' must take 1 parameter}} -} \ No newline at end of file + int v2 __attribute__((cleanup(c3))); // expected-error {{'cleanup' function 'c3' parameter has type 'struct s', expected type 'int *'}} +}