[PATCH] Preserve paramater attributes during template instantiation

Jordan Rose jordan_rose at apple.com
Wed Feb 27 09:34:03 PST 2013


Hi doug.gregor, rsmith,

Currently, we don't preserve attributes on ParmVarDecls when instantiating templates. This is a bug and can manifest in real problems when dealing with ARC in Objective-C++ because of the ``ns_consumed`` and ``cf_consumed`` attributes. The fix seems simple, but even after that I still can't get this test case to work:

```typedef void (*releaser_t)(__attribute__((ns_consumed)) id);
template <typename T>
void templateReleaser(__attribute__((ns_consumed)) T) {}
releaser_t r4 = templateReleaser<id>;```

What am I missing? And should this patch go in as is anyway?

(The static analyzer has the same issue as ARC, which is how this came up. <rdar://problem/12685622>)

http://llvm-reviews.chandlerc.com/D474

Files:
  lib/Sema/SemaTemplateInstantiate.cpp
  test/CodeGenObjCXX/arc-attrs.mm

Index: lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiate.cpp
+++ lib/Sema/SemaTemplateInstantiate.cpp
@@ -1716,7 +1716,9 @@
 
   NewParm->setScopeInfo(OldParm->getFunctionScopeDepth(),
                         OldParm->getFunctionScopeIndex() + indexAdjustment);
-  
+
+  InstantiateAttrs(TemplateArgs, OldParm, NewParm);
+
   return NewParm;  
 }
 
Index: test/CodeGenObjCXX/arc-attrs.mm
===================================================================
--- /dev/null
+++ test/CodeGenObjCXX/arc-attrs.mm
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -emit-llvm -fobjc-arc -O0 -o - %s | FileCheck %s
+
+id makeObject1() __attribute__((ns_returns_retained));
+id makeObject2() __attribute__((ns_returns_retained));
+void releaseObject(__attribute__((ns_consumed)) id);
+
+// CHECK: define void @_Z10sanityTestv
+void sanityTest() {
+  // CHECK: [[X:%.*]] = alloca i8*, align 8
+  // CHECK-NEXT: [[OBJ1:%.*]] = call i8* @_Z11makeObject1v()
+  // CHECK-NEXT: store i8* [[OBJ1]], i8** [[X]], align 8
+  id x = makeObject1();
+
+  // CHECK-NEXT: [[OBJ2:%.*]] = call i8* @_Z11makeObject2v()
+  // CHECK-NEXT: call void @_Z13releaseObjectP11objc_object(i8* [[OBJ2]])
+  releaseObject(makeObject2());
+
+  // CHECK-NEXT: call void @objc_storeStrong(i8** [[X]], i8* null)
+  // CHECK-NEXT: ret void
+}
+
+
+template <typename T>
+T makeObjectT1() __attribute__((ns_returns_retained));
+template <typename T>
+T makeObjectT2() __attribute__((ns_returns_retained));
+
+template <typename T>
+void releaseObjectT(__attribute__((ns_consumed)) T);  
+
+// CHECK: define void @_Z12templateTestv
+void templateTest() {
+  // CHECK: [[X:%.*]] = alloca i8*, align 8
+  // CHECK-NEXT: [[OBJ1:%.*]] = call i8* @_Z12makeObjectT1IU8__strongP11objc_objectET_v()
+  // CHECK-NEXT: store i8* [[OBJ1]], i8** [[X]], align 8
+  id x = makeObjectT1<id>();
+
+  // CHECK-NEXT: [[OBJ2:%.*]] = call i8* @_Z12makeObjectT2IU8__strongP11objc_objectET_v()
+  // CHECK-NEXT: call void @_Z13releaseObjectP11objc_object(i8* [[OBJ2]])
+  releaseObject(makeObjectT2<id>());
+
+  // CHECK-NEXT: [[OBJ3:%.*]] = call i8* @_Z11makeObject1v()
+  // CHECK-NEXT: call void @_Z14releaseObjectTIU8__strongP11objc_objectEvT_(i8* [[OBJ3]])
+  releaseObjectT(makeObject1());
+
+  // CHECK-NEXT: call void @objc_storeStrong(i8** [[X]], i8* null)
+  // CHECK-NEXT: ret void
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D474.1.patch
Type: text/x-patch
Size: 2437 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130227/3e5f2a9e/attachment.bin>


More information about the cfe-commits mailing list