[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