[cfe-commits] r133309 - in /cfe/trunk: docs/AutomaticReferenceCounting.html lib/Sema/TreeTransform.h lib/Sema/TypeLocBuilder.h test/SemaObjCXX/arc-templates.mm

Douglas Gregor dgregor at apple.com
Fri Jun 17 16:16:24 PDT 2011


Author: dgregor
Date: Fri Jun 17 18:16:24 2011
New Revision: 133309

URL: http://llvm.org/viewvc/llvm-project?rev=133309&view=rev
Log:
Objective-C++ ARC: eliminate the utterly unjustified loophole that
silently dropped ownership qualifiers that were being applied to
ownership-qualified, substituted type that was *not* a substituted
template type parameter. We now provide a diagnostic in such cases,
and recover by dropping the added qualifiers.

Document this behavior in the ARC specification.

Modified:
    cfe/trunk/docs/AutomaticReferenceCounting.html
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/lib/Sema/TypeLocBuilder.h
    cfe/trunk/test/SemaObjCXX/arc-templates.mm

Modified: cfe/trunk/docs/AutomaticReferenceCounting.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/AutomaticReferenceCounting.html?rev=133309&r1=133308&r2=133309&view=diff
==============================================================================
--- cfe/trunk/docs/AutomaticReferenceCounting.html (original)
+++ cfe/trunk/docs/AutomaticReferenceCounting.html Fri Jun 17 18:16:24 2011
@@ -598,12 +598,15 @@
 element type is a retainable object owner type.</p>
 
 <p>An <span class="term">ownership qualifier</span> is a type
-qualifier which applies only to retainable object owner types.  A
-program is ill-formed if it attempts to apply an ownership qualifier
+qualifier which applies only to retainable object owner types. An array type is
+ownership-qualified according to its element type, and adding an ownership 
+qualifier to an array type so qualifies its element type.</p>
+
+<p>A program is ill-formed if it attempts to apply an ownership qualifier
 to a type which is already ownership-qualified, even if it is the same
-qualifier.  An array type is ownership-qualified according to its
-element type, and adding an ownership qualifier to an array type so
-qualifies its element type.</p>
+qualifier. There is a single exception to this rule: an ownership qualifier 
+may be applied to a substituted template type parameter, which overrides the
+ownership qualifier provided by the template argument.</p>
 
 <p>Except as described under
 the <a href="#ownership.inference">inference rules</a>, a program is
@@ -612,7 +615,7 @@
 
 <div class="rationale"><p>Rationale: these rules, together with the
 inference rules, ensure that all objects and lvalues of retainable
-object pointer type have an ownership qualifier.</p></div>
+object pointer type have an ownership qualifier. The ability to override an ownership qualifier during template substitution is required to counteract the <a href="#ownership.inference.template_arguments">inference of <tt>__strong</tt> for template type arguments</a>. </p></div>
 
 <p>There are four ownership qualifiers:</p>
 

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=133309&r1=133308&r2=133309&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Fri Jun 17 18:16:24 2011
@@ -3177,8 +3177,7 @@
   if (Quals.hasObjCLifetime()) {
     if (!Result->isObjCLifetimeType() && !Result->isDependentType())
       Quals.removeObjCLifetime();
-    else if (Result.getObjCLifetime() && 
-             Result.getObjCLifetime() != Quals.getObjCLifetime()) {
+    else if (Result.getObjCLifetime()) {
       // Objective-C ARC: 
       //   A lifetime qualifier applied to a substituted template parameter
       //   overrides the lifetime qualifier from the template argument.
@@ -3195,8 +3194,12 @@
                                                               Replacement);
         TLB.TypeWasModifiedSafely(Result);
       } else {
-        // Otherwise, drop the new qualifier.
-        // FIXME: I don't recall the justification for this!
+        // Otherwise, complain about the addition of a qualifier to an
+        // already-qualified type.
+        SourceRange R = TLB.getTemporaryTypeLoc(Result).getSourceRange();
+        SemaRef.Diag(R.getBegin(), diag::err_attr_objc_lifetime_redundant)
+          << Result << R;
+        
         Quals.removeObjCLifetime();
       }
     }

Modified: cfe/trunk/lib/Sema/TypeLocBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TypeLocBuilder.h?rev=133309&r1=133308&r2=133309&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TypeLocBuilder.h (original)
+++ cfe/trunk/lib/Sema/TypeLocBuilder.h Fri Jun 17 18:16:24 2011
@@ -147,7 +147,7 @@
 
     Index -= LocalSize;
 
-    return getTypeLoc(T);
+    return getTemporaryTypeLoc(T);
   }
 
   /// Grow to the given capacity.
@@ -179,15 +179,17 @@
     reserve(Size);
     Index -= Size;
 
-    return getTypeLoc(T);
+    return getTemporaryTypeLoc(T);
   }
 
-
-  // This is private because, when we kill off TypeSourceInfo in favor
-  // of TypeLoc, we'll want an interface that creates a TypeLoc given
-  // an ASTContext, and we don't want people to think they can just
-  // use this as an equivalent.
-  TypeLoc getTypeLoc(QualType T) {
+public:
+  /// \brief Retrieve a temporary TypeLoc that refers into this \c TypeLocBuilder
+  /// object.
+  ///
+  /// The resulting \c TypeLoc should only be used so long as the 
+  /// \c TypeLocBuilder is active and has not had more type information
+  /// pushed into it.
+  TypeLoc getTemporaryTypeLoc(QualType T) {
 #ifndef NDEBUG
     assert(LastTy == T && "type doesn't match last type pushed!");
 #endif

Modified: cfe/trunk/test/SemaObjCXX/arc-templates.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/arc-templates.mm?rev=133309&r1=133308&r2=133309&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjCXX/arc-templates.mm (original)
+++ cfe/trunk/test/SemaObjCXX/arc-templates.mm Fri Jun 17 18:16:24 2011
@@ -94,6 +94,16 @@
 int check_make_weak1[is_same<make_weak<__strong id>::type, __weak id>::value? 1 : -1];
 int check_make_weak2[is_same<make_weak<__autoreleasing id>::type, __weak id>::value? 1 : -1];
 
+template<typename T>
+struct make_weak_fail {
+  typedef T T_type;
+  typedef __weak T_type type; // expected-error{{the type 'T_type' (aka '__weak id') already has retainment attributes set on it}} \
+  // expected-error{{the type 'T_type' (aka '__strong id') already has retainment attributes set on it}}
+};
+
+int check_make_weak_fail0[is_same<make_weak_fail<__weak id>::type, __weak id>::value? 1 : -1]; // expected-note{{in instantiation of template class 'make_weak_fail<__weak id>' requested here}}
+
+int check_make_weak_fail1[is_same<make_weak_fail<id>::type, __weak id>::value? -1 : 1]; // expected-note{{in instantiation of template class 'make_weak_fail<id>' requested here}}
 
 // Check template argument deduction from function templates.
 template<typename T> struct identity { };





More information about the cfe-commits mailing list