'pure' and 'const' functions should also be marked nounwind. Migrate
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
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 023dd22..dc3e702 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -739,10 +739,15 @@
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;
}
diff --git a/test/CodeGen/libcalls.c b/test/CodeGen/libcalls.c
index 5ff684f..458c591 100644
--- a/test/CodeGen/libcalls.c
+++ b/test/CodeGen/libcalls.c
@@ -24,9 +24,9 @@
// 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
diff --git a/test/CodeGen/struct-passing.c b/test/CodeGen/struct-passing.c
index 8e5c0ad..efb00ef 100644
--- a/test/CodeGen/struct-passing.c
+++ b/test/CodeGen/struct-passing.c
@@ -16,8 +16,8 @@
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
index 0000000..7089207
--- /dev/null
+++ b/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp
@@ -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();
+}