[cfe-commits] r172768 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/AST/ASTContext.cpp lib/Sema/SemaType.cpp test/SemaObjC/arc-objc-lifetime.m test/SemaObjCXX/arc-templates.mm
Douglas Gregor
dgregor at apple.com
Thu Jan 17 15:36:46 PST 2013
Author: dgregor
Date: Thu Jan 17 17:36:45 2013
New Revision: 172768
URL: http://llvm.org/viewvc/llvm-project?rev=172768&view=rev
Log:
In Objective-C ARC, completely ignore ownership qualifiers on the
return type of a function by canonicalizing them away. They are
useless anyway, and conflict with our rules for template argument
deduction and __strong. Fixes <rdar://problem/12367446>.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/Sema/SemaType.cpp
cfe/trunk/test/SemaObjC/arc-objc-lifetime.m
cfe/trunk/test/SemaObjCXX/arc-templates.mm
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=172768&r1=172767&r2=172768&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Jan 17 17:36:45 2013
@@ -3763,6 +3763,10 @@
def err_arc_multiple_method_decl : Error<
"multiple methods named %0 found with mismatched result, "
"parameter type or attributes">;
+def warn_arc_lifetime_result_type : Warning<
+ "ARC %select{unused|__unsafe_unretained|__strong|__weak|__autoreleasing}0 "
+ "lifetime qualifier on return type is ignored">,
+ InGroup<IgnoredQualifiers>;
let CategoryName = "ARC Retain Cycle" in {
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=172768&r1=172767&r2=172768&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Thu Jan 17 17:36:45 2013
@@ -2602,6 +2602,13 @@
return QualType(New, 0);
}
+/// \brief Determine whether \p T is canonical as the result type of a function.
+static bool isCanonicalResultType(QualType T) {
+ return T.isCanonical() &&
+ (T.getObjCLifetime() == Qualifiers::OCL_None ||
+ T.getObjCLifetime() == Qualifiers::OCL_ExplicitNone);
+}
+
/// getFunctionType - Return a normal function type with a typed argument
/// list. isVariadic indicates whether the argument list includes '...'.
QualType
@@ -2620,7 +2627,7 @@
// Determine whether the type being created is already canonical or not.
bool isCanonical =
- EPI.ExceptionSpecType == EST_None && ResultTy.isCanonical() &&
+ EPI.ExceptionSpecType == EST_None && isCanonicalResultType(ResultTy) &&
!EPI.HasTrailingReturn;
for (unsigned i = 0; i != NumArgs && isCanonical; ++i)
if (!ArgArray[i].isCanonicalAsParam())
@@ -2646,7 +2653,15 @@
CanonicalEPI.ExtInfo
= CanonicalEPI.ExtInfo.withCallingConv(getCanonicalCallConv(CallConv));
- Canonical = getFunctionType(getCanonicalType(ResultTy),
+ // Result types do not have ARC lifetime qualifiers.
+ QualType CanResultTy = getCanonicalType(ResultTy);
+ if (ResultTy.getQualifiers().hasObjCLifetime()) {
+ Qualifiers Qs = CanResultTy.getQualifiers();
+ Qs.removeObjCLifetime();
+ CanResultTy = getQualifiedType(CanResultTy.getUnqualifiedType(), Qs);
+ }
+
+ Canonical = getFunctionType(CanResultTy,
CanonicalArgs.data(), NumArgs,
CanonicalEPI);
Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=172768&r1=172767&r2=172768&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Thu Jan 17 17:36:45 2013
@@ -2471,6 +2471,44 @@
S);
}
+ // Objective-C ARC ownership qualifiers are ignored on the function
+ // return type (by type canonicalization). Complain if this attribute
+ // was written here.
+ if (T.getQualifiers().hasObjCLifetime()) {
+ SourceLocation AttrLoc;
+ if (chunkIndex + 1 < D.getNumTypeObjects()) {
+ DeclaratorChunk ReturnTypeChunk = D.getTypeObject(chunkIndex + 1);
+ for (const AttributeList *Attr = ReturnTypeChunk.getAttrs();
+ Attr; Attr = Attr->getNext()) {
+ if (Attr->getKind() == AttributeList::AT_ObjCOwnership) {
+ AttrLoc = Attr->getLoc();
+ break;
+ }
+ }
+ }
+ if (AttrLoc.isInvalid()) {
+ for (const AttributeList *Attr
+ = D.getDeclSpec().getAttributes().getList();
+ Attr; Attr = Attr->getNext()) {
+ if (Attr->getKind() == AttributeList::AT_ObjCOwnership) {
+ AttrLoc = Attr->getLoc();
+ break;
+ }
+ }
+ }
+
+ if (AttrLoc.isValid()) {
+ // The ownership attributes are almost always written via
+ // the predefined
+ // __strong/__weak/__autoreleasing/__unsafe_unretained.
+ if (AttrLoc.isMacroID())
+ AttrLoc = S.SourceMgr.getImmediateExpansionRange(AttrLoc).first;
+
+ S.Diag(AttrLoc, diag::warn_arc_lifetime_result_type)
+ << T.getQualifiers().getObjCLifetime();
+ }
+ }
+
if (LangOpts.CPlusPlus && D.getDeclSpec().isTypeSpecOwned()) {
// C++ [dcl.fct]p6:
// Types shall not be defined in return or parameter types.
Modified: cfe/trunk/test/SemaObjC/arc-objc-lifetime.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/arc-objc-lifetime.m?rev=172768&r1=172767&r2=172768&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/arc-objc-lifetime.m (original)
+++ cfe/trunk/test/SemaObjC/arc-objc-lifetime.m Thu Jan 17 17:36:45 2013
@@ -67,3 +67,22 @@
- (void)createInferiorTransportAndSetEnvironment:(NSMutableDictionary*)environment error:(__autoreleasing NSError**)error {}
@end
+// <rdar://problem/12367446>
+typedef __strong id strong_id;
+typedef NSObject *NSObject_ptr;
+typedef __strong NSObject *strong_NSObject_ptr;
+
+// Warn
+__strong id f1(); // expected-warning{{ARC __strong lifetime qualifier on return type is ignored}}
+NSObject __unsafe_unretained *f2(int); // expected-warning{{ARC __unsafe_unretained lifetime qualifier on return type is ignored}}
+__autoreleasing NSObject *f3(void); // expected-warning{{ARC __autoreleasing lifetime qualifier on return type is ignored}}
+NSObject * __strong f4(void); // expected-warning{{ARC __strong lifetime qualifier on return type is ignored}}
+NSObject_ptr __strong f5(); // expected-warning{{ARC __strong lifetime qualifier on return type is ignored}}
+
+typedef __strong id (*fptr)(int); // expected-warning{{ARC __strong lifetime qualifier on return type is ignored}}
+typedef __strong id (^block_ptr)(int); // expected-warning{{ARC __strong lifetime qualifier on return type is ignored}}
+
+// Don't warn
+strong_id f6();
+strong_NSObject_ptr f7();
+
Modified: cfe/trunk/test/SemaObjCXX/arc-templates.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/arc-templates.mm?rev=172768&r1=172767&r2=172768&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjCXX/arc-templates.mm (original)
+++ cfe/trunk/test/SemaObjCXX/arc-templates.mm Thu Jan 17 17:36:45 2013
@@ -283,3 +283,12 @@
testing(@"hi");
}
}
+
+namespace rdar12367446 {
+ template <class T> class A;
+ template <class R> class A<R()> {};
+
+ void test() {
+ A<id()> value;
+ }
+}
More information about the cfe-commits
mailing list