From: John McCall Date: Tue, 8 Mar 2011 04:17:03 +0000 (+0000) Subject: objc_gc wants a pointer type, not a function type; give it a more appropriate X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2792fa5115c5de7cbe11d99d23663c569bfb4cae;p=clang objc_gc wants a pointer type, not a function type; give it a more appropriate diagnostic. Also, these attributes are commonly written with macros which we actually pre-define, so instead of expanding the macro location, refer to the instantiation location and name it using the macro loc. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127219 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 7cd6d9ed7f..e862960379 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1115,7 +1115,9 @@ def err_attribute_wrong_decl_type : Error< "classes and virtual methods|functions, methods, and parameters|" "classes|virtual methods|class members|variables|methods}1">; def warn_function_attribute_wrong_type : Warning< - "%0 only applies to function types; type here is %1">; + "'%0' only applies to function types; type here is %1">; +def warn_pointer_attribute_wrong_type : Warning< + "'%0' only applies to pointer types; type here is %1">; def warn_gnu_inline_attribute_requires_inline : Warning< "'gnu_inline' attribute requires function to be marked 'inline'," " attribute ignored">; diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 9d973237dd..772a557545 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -22,6 +22,7 @@ #include "clang/AST/Expr.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/TargetInfo.h" +#include "clang/Lex/Preprocessor.h" #include "clang/Sema/DeclSpec.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/Support/ErrorHandling.h" @@ -70,6 +71,42 @@ static bool isOmittedBlockReturnType(const Declarator &D) { return false; } +/// diagnoseBadTypeAttribute - Diagnoses a type attribute which +/// doesn't apply to the given type. +static void diagnoseBadTypeAttribute(Sema &S, const AttributeList &attr, + QualType type) { + bool useInstantiationLoc = false; + + unsigned diagID = 0; + switch (attr.getKind()) { + case AttributeList::AT_objc_gc: + diagID = diag::warn_pointer_attribute_wrong_type; + useInstantiationLoc = true; + break; + + default: + // Assume everything else was a function attribute. + diagID = diag::warn_function_attribute_wrong_type; + break; + } + + SourceLocation loc = attr.getLoc(); + llvm::StringRef name = attr.getName()->getName(); + + // The GC attributes are usually written with macros; special-case them. + if (useInstantiationLoc && loc.isMacroID() && attr.getParameterName()) { + SourceLocation instLoc = S.getSourceManager().getInstantiationLoc(loc); + llvm::StringRef macro = S.getPreprocessor().getSpelling(instLoc); + if ((macro == "__strong" && attr.getParameterName()->isStr("strong")) || + (macro == "__weak" && attr.getParameterName()->isStr("weak"))) { + loc = instLoc; + name = macro; + } + } + + S.Diag(loc, diagID) << name << type; +} + // objc_gc applies to Objective-C pointers or, otherwise, to the // smallest available pointer type (i.e. 'void*' in 'void**'). #define OBJC_POINTER_TYPE_ATTRS_CASELIST \ @@ -162,11 +199,8 @@ namespace { void diagnoseIgnoredTypeAttrs(QualType type) const { for (llvm::SmallVectorImpl::const_iterator i = ignoredTypeAttrs.begin(), e = ignoredTypeAttrs.end(); - i != e; ++i) { - AttributeList &attr = **i; - getSema().Diag(attr.getLoc(), diag::warn_function_attribute_wrong_type) - << attr.getName() << type; - } + i != e; ++i) + diagnoseBadTypeAttribute(getSema(), **i, type); } ~TypeProcessingState() { @@ -287,9 +321,8 @@ static void distributeObjCPointerTypeAttr(TypeProcessingState &state, } } error: - - state.getSema().Diag(attr.getLoc(), diag::warn_function_attribute_wrong_type) - << attr.getName() << type; + + diagnoseBadTypeAttribute(state.getSema(), attr, type); } /// Distribute an objc_gc type attribute that was written on the @@ -374,8 +407,7 @@ static void distributeFunctionTypeAttr(TypeProcessingState &state, } } - state.getSema().Diag(attr.getLoc(), diag::warn_function_attribute_wrong_type) - << attr.getName() << type; + diagnoseBadTypeAttribute(state.getSema(), attr, type); } /// Try to distribute a function type attribute to the innermost diff --git a/test/SemaObjC/attr-objc-gc.m b/test/SemaObjC/attr-objc-gc.m index fd818557f5..cfe59516ee 100644 --- a/test/SemaObjC/attr-objc-gc.m +++ b/test/SemaObjC/attr-objc-gc.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify %s static id __attribute((objc_gc(weak))) a; static id __attribute((objc_gc(strong))) b; @@ -6,3 +6,7 @@ static id __attribute((objc_gc())) c; // expected-error{{'objc_gc' attribute req static id __attribute((objc_gc(123))) d; // expected-error{{'objc_gc' attribute requires parameter 1 to be a string}} static id __attribute((objc_gc(foo, 456))) e; // expected-error{{attribute takes one argument}} static id __attribute((objc_gc(hello))) f; // expected-warning{{'objc_gc' attribute argument not supported: 'hello'}} + +static int __attribute__((objc_gc(weak))) g; // expected-warning {{'objc_gc' only applies to pointer types; type here is 'int'}} + +static __weak int h; // expected-warning {{'__weak' only applies to pointer types; type here is 'int'}}