================
@@ -64,3 +64,105 @@ __attribute__((pure)) int func8(void);
return 12;
}
+[[noreturn]] void direct_noreturn(void);
+// FIXME: the cast should not be necessary.
+void (*indirect_noreturn)(void) __attribute__((noreturn)) =
(__typeof__(indirect_noreturn)) direct_noreturn;
+void returns_okay();
+
+__attribute__((const)) int noreturn_test1(void) {
+ returns_okay();
+ return 12;
+}
+
+__attribute__((const)) int noreturn_test2(void) { // expected-note {{function
declared 'const' here}}
+ direct_noreturn(); // expected-warning {{alling a 'noreturn' function from a
function with the 'const' attribute is undefined behavior}}
+ return 12;
+}
+
+__attribute__((const)) int noreturn_test3(void) { // expected-note {{function
declared 'const' here}}
+ indirect_noreturn(); // expected-warning {{calling a 'noreturn' function
from a function with the 'const' attribute is undefined behavior}}
+ return 12;
+}
+
+__attribute__((const)) int noreturn_test4(void) { // expected-note {{function
declared 'const' here}}
+ // This should not be diagnosed.
+ (void)sizeof((direct_noreturn(), 1));
+
+#ifdef __cplusplus
+ if constexpr(false) {
+ // This should not be diagnosed.
+ direct_noreturn();
+ }
+#endif // __cplusplus
+
+ if (0) {
+ // FIXME: it would be better if this was not diagnosed because it is
+ // statically known to be unreachable.
+ direct_noreturn(); // expected-warning {{calling a 'noreturn' function
from a function with the 'const' attribute is undefined behavior}}
+ }
+
+ return 12;
+}
+
+__attribute__((pure)) int noreturn_test5(int x) { // expected-note {{function
declared 'pure' here}}
+ if (x)
+ direct_noreturn(); // expected-warning {{calling a 'noreturn' function
from a function with the 'pure' attribute is undefined behavior}}
+ return 12;
+}
+
+// FIXME: should this be diagnosed because of the noreturn call?
+[[gnu::pure]] int noreturn_test6(int array[(direct_noreturn(), 1)]);
+
+#ifdef __cplusplus
+
+template <typename Ty>
+int noreturn_test7(void) {
+ direct_noreturn(); // okay
+ return 12;
+}
+
+template <>
+__attribute__((const)) int noreturn_test7<int>() { // expected-note {{function
declared 'const' here}}
+ direct_noreturn(); // expected-warning {{calling a 'noreturn' function from
a function with the 'const' attribute is undefined behavior}}
+ return 12;
+}
+
+template <typename Ty>
+__attribute__((pure)) int noreturn_test8() { // expected-note {{function
declared 'pure' here}}
+ // Diagnosed even though noreturn_test8 is not instantiated
+ direct_noreturn(); // expected-warning {{calling a 'noreturn' function from
a function with the 'pure' attribute is undefined behavior}}
+ return 12;
+}
+
+template <typename T>
+[[gnu::pure]] int noreturn_test9() { // expected-note {{function declared
'pure' here}}
+ T::nrcall(); // expected-warning {{calling a 'noreturn' function from a
function with the 'pure' attribute is undefined behavior}}
+ return 12;
----------------
AaronBallman wrote:
> Could you add `S{}.mem_nrcall();` here too?
That's tested in `memfn()`.
> Also, perhaps a dependent fptr? Ala-`indirect_noreturn`, as a member? I
> believe both will work, but would be nice to have the coverage.
Sure!
https://github.com/llvm/llvm-project/pull/206134
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits