]> granicus.if.org Git - clang/commitdiff
'pure' and 'const' functions should also be marked nounwind. Migrate
authorEric Christopher <echristo@apple.com>
Mon, 15 Aug 2011 22:38:22 +0000 (22:38 +0000)
committerEric Christopher <echristo@apple.com>
Mon, 15 Aug 2011 22:38:22 +0000 (22:38 +0000)
test over from llvm/test/FrontendC++ and update others to account for
the change.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@137669 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGCall.cpp
test/CodeGen/libcalls.c
test/CodeGen/struct-passing.c
test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp [new file with mode: 0644]

index 023dd2267cc61b210b886ee93e7ad45c204d3869..dc3e702d6a38a54ba5a157c37adf8b14cfe0a986 100644 (file)
@@ -739,10 +739,15 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
 
     if (TargetDecl->hasAttr<NoReturnAttr>())
       FuncAttrs |= llvm::Attribute::NoReturn;
-    if (TargetDecl->hasAttr<ConstAttr>())
+
+    // 'const' and 'pure' attribute functions are also nounwind.
+    if (TargetDecl->hasAttr<ConstAttr>()) {
       FuncAttrs |= llvm::Attribute::ReadNone;
-    else if (TargetDecl->hasAttr<PureAttr>())
+      FuncAttrs |= llvm::Attribute::NoUnwind;
+    } else if (TargetDecl->hasAttr<PureAttr>()) {
       FuncAttrs |= llvm::Attribute::ReadOnly;
+      FuncAttrs |= llvm::Attribute::NoUnwind;
+    }
     if (TargetDecl->hasAttr<MallocAttr>())
       RetAttrs |= llvm::Attribute::NoAlias;
   }
index 5ff684fd5b6648bf5b93a0254d41a393885d877d..458c591837ff02134b5937935d872a3b6423f9f4 100644 (file)
@@ -24,9 +24,9 @@ void test_sqrt(float a0, double a1, long double a2) {
 // CHECK-YES: declare float @sqrtf(float)
 // CHECK-YES: declare double @sqrt(double)
 // CHECK-YES: declare x86_fp80 @sqrtl(x86_fp80)
-// CHECK-NO: declare float @sqrtf(float) readnone
-// CHECK-NO: declare double @sqrt(double) readnone
-// CHECK-NO: declare x86_fp80 @sqrtl(x86_fp80) readnone
+// CHECK-NO: declare float @sqrtf(float) nounwind readnone
+// CHECK-NO: declare double @sqrt(double) nounwind readnone
+// CHECK-NO: declare x86_fp80 @sqrtl(x86_fp80) nounwind readnone
 
 // CHECK-YES: define void @test_pow
 // CHECK-NO: define void @test_pow
index 8e5c0adcfc10a162ca0bc63820aac550035b7017..efb00efd53ab262df59a4b1d316c9bdfe650bd02 100644 (file)
@@ -16,8 +16,8 @@ void __attribute__((pure)) f5(T1 a);
 
 void *ps[] = { f0, f1, f2, f3, f4, f5 };
 
-// CHECK: declare i32 @f0() readnone
-// CHECK: declare i32 @f1() readonly
+// CHECK: declare i32 @f0() nounwind readnone
+// CHECK: declare i32 @f1() nounwind readonly
 // CHECK: declare void @f2({{.*}} sret)
 // CHECK: declare void @f3({{.*}} sret)
 // CHECK: declare void @f4({{.*}} byval align 4)
diff --git a/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp b/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp
new file mode 100644 (file)
index 0000000..7089207
--- /dev/null
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fexceptions -emit-llvm %s -o - | grep nounwind | count 4
+int c(void) __attribute__((const));
+int p(void) __attribute__((pure));
+int t(void);
+
+int f(void) {
+  return c() + p() + t();
+}