| Issue |
208705
|
| Summary |
[clang][Sema] Segfault in Expr::getReferencedDeclOfCallee via CheckNoInlineAttr during template instantiation of variadic function with [[clang::noinline]] on return statement
|
| Labels |
|
| Assignees |
|
| Reporter |
YuanchengJiang
|
The following code:
```cpp
template<int D>
template<int D>
int dependent(int x){ return x + D;}
[[clang::always_inline]]
int non_dependent(int x){return x;}
template<int ... D>
int variadic_qux(int x) {
[[msvc::noinline]] return non_dependent(x) + (dependent<D>(x) + ...);
}
void use() {
variadic_baz<0, 1, 2>(0); // #VARIADIC_INST
```
Resulted in this output:
```
/tmp/test.cpp:7:3: warning: 'msvc::noinline' attribute only applies to functions and statements [-Wignored-attributes]
7 | [[msvc::noinline]] static int j = bar();
| ^
/tmp/test.cpp:7:35: error: use of undeclared identifier 'bar'
7 | [[msvc::noinline]] static int j = bar();
| ^~~
/tmp/test.cpp:10:3: warning: 'clang::noinline' attribute only applies to functions and statements [-Wignored-attributes]
10 | [[clang::noinline]] static int i = bar();
| ^
/tmp/test.cpp:10:36: error: use of undeclared identifier 'bar'
10 | [[clang::noinline]] static int i = bar();
| ^~~
/tmp/test.cpp:11:15: error: expected ';' after struct
11 | struct Tag1 {}
| ^
| ;
/tmp/test.cpp:12:15: error: expected ';' after struct
12 | struct Tag4 {}
| ^
| ;
/tmp/test.cpp:25:5: error: 'clang::noinline' attribute takes no arguments
25 | [[clang::noinline(0)]] bar(); // expected-error {{'clang::noinline' attribute takes no arguments}}
| ^
/tmp/test.cpp:27:23: warning: 'clang::noinline' attribute is ignored because there exists no call _expression_ inside the statement [-Wignored-attributes]
27 | [[clang::noinline]] x = 0; // expected-warning {{'clang::noinline' attribute is ignored because there exists no call _expression_ inside the statement}}
| ^
/tmp/test.cpp:28:23: warning: 'clang::noinline' attribute is ignored because there exists no call _expression_ inside the statement [-Wignored-attributes]
28 | [[clang::noinline]] { asm("nop"); } // expected-warning {{'clang::noinline' attribute is ignored because there exists no call _expression_ inside the statement}}
| ^
/tmp/test.cpp:29:5: warning: 'clang::noinline' attribute only applies to functions and statements [-Wignored-attributes]
29 | [[clang::noinline]] label: x = 1; // expected-warning {{'clang::noinline' attribute only applies to functions and statements}}
| ^
/tmp/test.cpp:32:23: warning: statement attribute 'clang::noinline' has higher precedence than function attribute 'always_inline' [-Wignored-attributes]
32 | [[clang::noinline]] always_inline_fn(); // expected-warning {{statement attribute 'clang::noinline' has higher precedence than function attribute 'always_inline'}}
| ^
/tmp/test.cpp:5:24: note: conflicting attribute is here
5 | [[gnu::always_inline]] void always_inline_fn(void) { }
| ^
/tmp/test.cpp:33:23: warning: statement attribute 'clang::noinline' has higher precedence than function attribute 'flatten' [-Wignored-attributes]
33 | [[clang::noinline]] flatten_fn(); // expected-warning {{statement attribute 'clang::noinline' has higher precedence than function attribute 'flatten'}}
| ^
/tmp/test.cpp:3:18: note: conflicting attribute is here
3 | [[gnu::flatten]] void flatten_fn(void) { }
| ^
/tmp/test.cpp:36:21: warning: attribute is ignored on this statement as it only applies to functions; use '[[clang::noinline]]' on statements [-Wignored-attributes]
36 | [[gnu::noinline]] bar(); // expected-warning {{attribute is ignored on this statement as it only applies to functions; use '[[clang::noinline]]' on statements}}
| ^
/tmp/test.cpp:37:29: warning: attribute is ignored on this statement as it only applies to functions; use '[[clang::noinline]]' on statements [-Wignored-attributes]
37 | __attribute__((noinline)) bar(); // expected-warning {{attribute is ignored on this statement as it only applies to functions; use '[[clang::noinline]]' on statements}}
| ^
/tmp/test.cpp:41:5: error: 'msvc::noinline' attribute takes no arguments
41 | [[msvc::noinline(0)]] bar(); // expected-error {{'msvc::noinline' attribute takes no arguments}}
| ^
/tmp/test.cpp:43:22: warning: 'msvc::noinline' attribute is ignored because there exists no call _expression_ inside the statement [-Wignored-attributes]
43 | [[msvc::noinline]] x = 0; // expected-warning {{'msvc::noinline' attribute is ignored because there exists no call _expression_ inside the statement}}
| ^
/tmp/test.cpp:44:22: warning: 'msvc::noinline' attribute is ignored because there exists no call _expression_ inside the statement [-Wignored-attributes]
44 | [[msvc::noinline]] { asm("nop"); } // expected-warning {{'msvc::noinline' attribute is ignored because there exists no call _expression_ inside the statement}}
| ^
/tmp/test.cpp:45:5: warning: 'msvc::noinline' attribute only applies to functions and statements [-Wignored-attributes]
45 | [[msvc::noinline]] label: x = 1; // expected-warning {{'msvc::noinline' attribute only applies to functions and statements}}
| ^
/tmp/test.cpp:47:22: warning: statement attribute 'msvc::noinline' has higher precedence than function attribute 'always_inline' [-Wignored-attributes]
47 | [[msvc::noinline]] always_inline_fn(); // expected-warning {{statement attribute 'msvc::noinline' has higher precedence than function attribute 'always_inline'}}
| ^
/tmp/test.cpp:5:24: note: conflicting attribute is here
5 | [[gnu::always_inline]] void always_inline_fn(void) { }
| ^
/tmp/test.cpp:48:22: warning: statement attribute 'msvc::noinline' has higher precedence than function attribute 'flatten' [-Wignored-attributes]
48 | [[msvc::noinline]] flatten_fn(); // expected-warning {{statement attribute 'msvc::noinline' has higher precedence than function attribute 'flatten'}}
| ^
/tmp/test.cpp:3:18: note: conflicting attribute is here
3 | [[gnu::flatten]] void flatten_fn(void) { }
| ^
/tmp/test.cpp:56:33: error: comparison between pointer and integer ('void (*)()' and 'int')
56 | [[clang::noinline]] return foo<D-1>(x + 1);
| ~~~^~~~
/tmp/test.cpp:56:23: warning: 'clang::noinline' attribute is ignored because there exists no call _expression_ inside the statement [-Wignored-attributes]
56 | [[clang::noinline]] return foo<D-1>(x + 1);
| ^
/tmp/test.cpp:59:3: warning: attribute declaration must precede definition [-Wignored-attributes]
59 | [[clang::always_inline]]
| ^
/tmp/test.cpp:55:5: note: previous definition is here
55 | int dependent(int x) {
| ^
/tmp/test.cpp:60:5: error: redefinition of 'dependent'
60 | int dependent(int x){ return x + D;}
| ^
/tmp/test.cpp:55:5: note: previous definition is here
55 | int dependent(int x) {
| ^
/tmp/test.cpp:70:23: warning: statement attribute 'clang::noinline' has higher precedence than function attribute 'always_inline' [-Wignored-attributes]
70 | [[clang::noinline]] non_dependent(x);
| ^
/tmp/test.cpp:63:1: note: conflicting attribute is here
63 | int non_dependent(int x){return x;}
| ^
/tmp/test.cpp:78:25: warning: statement attribute 'clang::noinline' has higher precedence than function attribute 'always_inline' [-Wignored-attributes]
78 | [[clang::noinline]] return non_dependent(x), baz<D-1>(x + 1);
| ^
/tmp/test.cpp:63:1: note: conflicting attribute is here
63 | int non_dependent(int x){return x;}
| ^
/tmp/test.cpp:92:23: warning: statement attribute 'clang::noinline' has higher precedence than function attribute 'always_inline' [-Wignored-attributes]
92 | [[clang::noinline]] return non_dependent(x) + (dependent<D>(x) + ...);
| ^
/tmp/test.cpp:63:1: note: conflicting attribute is here
63 | int non_dependent(int x){return x;}
| ^
/tmp/test.cpp:98:22: warning: statement attribute 'msvc::noinline' has higher precedence than function attribute 'always_inline' [-Wignored-attributes]
98 | [[msvc::noinline]] non_dependent(x);
| ^
/tmp/test.cpp:63:1: note: conflicting attribute is here
63 | int non_dependent(int x){return x;}
| ^
/tmp/test.cpp:106:24: warning: statement attribute 'msvc::noinline' has higher precedence than function attribute 'always_inline' [-Wignored-attributes]
106 | [[msvc::noinline]] return non_dependent(x), qux<D-1>(x + 1);
| ^
/tmp/test.cpp:63:1: note: conflicting attribute is here
63 | int non_dependent(int x){return x;}
| ^
/tmp/test.cpp:120:22: warning: statement attribute 'msvc::noinline' has higher precedence than function attribute 'always_inline' [-Wignored-attributes]
120 | [[msvc::noinline]] return non_dependent(x) + (dependent<D>(x) + ...);
| ^
/tmp/test.cpp:63:1: note: conflicting attribute is here
63 | int non_dependent(int x){return x;}
| ^
/tmp/test.cpp:128:24: error: use of undeclared identifier 'get_line_constexpr'
128 | const int global_three(get_line_constexpr());
| ^~~~~~~~~~~~~~~~~~
/tmp/test.cpp:130:18: error: use of undeclared identifier 'get_line_constexpr'
130 | int global_two = get_line_constexpr();
| ^~~~~~~~~~~~~~~~~~
/tmp/test.cpp:165:2: error: expected ';' after struct
165 | }
| ^
| ;
/tmp/test.cpp:78:25: warning: statement attribute 'clang::noinline' has higher precedence than function attribute 'always_inline' [-Wignored-attributes]
78 | [[clang::noinline]] return non_dependent(x), baz<D-1>(x + 1);
| ^
/tmp/test.cpp:123:3: note: in instantiation of function template specialization 'baz<3>' requested here
123 | baz<3>(0); // #BAZ_INST
| ^
/tmp/test.cpp:67:1: note: conflicting attribute is here
67 | int baz(int x) { // #BAZ
| ^
/tmp/test.cpp:78:25: warning: statement attribute 'clang::noinline' has higher precedence than function attribute 'always_inline' [-Wignored-attributes]
78 | [[clang::noinline]] return non_dependent(x), baz<D-1>(x + 1);
| ^
/tmp/test.cpp:78:50: note: in instantiation of function template specialization 'baz<2>' requested here
78 | [[clang::noinline]] return non_dependent(x), baz<D-1>(x + 1);
| ^
/tmp/test.cpp:123:3: note: in instantiation of function template specialization 'baz<3>' requested here
123 | baz<3>(0); // #BAZ_INST
| ^
/tmp/test.cpp:67:1: note: conflicting attribute is here
67 | int baz(int x) { // #BAZ
| ^
/tmp/test.cpp:78:25: warning: statement attribute 'clang::noinline' has higher precedence than function attribute 'always_inline' [-Wignored-attributes]
78 | [[clang::noinline]] return non_dependent(x), baz<D-1>(x + 1);
| ^
/tmp/test.cpp:78:50: note: in instantiation of function template specialization 'baz<1>' requested here
78 | [[clang::noinline]] return non_dependent(x), baz<D-1>(x + 1);
| ^
/tmp/test.cpp:78:50: note: in instantiation of function template specialization 'baz<2>' requested here
/tmp/test.cpp:123:3: note: in instantiation of function template specialization 'baz<3>' requested here
123 | baz<3>(0); // #BAZ_INST
| ^
/tmp/test.cpp:67:1: note: conflicting attribute is here
67 | int baz(int x) { // #BAZ
| ^
/tmp/test.cpp:92:50: error: no matching function for call to 'dependent'
92 | [[clang::noinline]] return non_dependent(x) + (dependent<D>(x) + ...);
| ^~~~~~~~~~~~
/tmp/test.cpp:124:3: note: in instantiation of function template specialization 'variadic_baz<0, 1, 2>' requested here
124 | variadic_baz<0, 1, 2>(0); // #VARIADIC_INST
| ^
/tmp/test.cpp:60:5: note: candidate template ignored: substitution failure [with D = 2]
60 | int dependent(int x){ return x + D;}
| ^
/tmp/test.cpp:92:50: error: no matching function for call to 'dependent'
92 | [[clang::noinline]] return non_dependent(x) + (dependent<D>(x) + ...);
| ^~~~~~~~~~~~
/tmp/test.cpp:60:5: note: candidate template ignored: substitution failure [with D = 1]
60 | int dependent(int x){ return x + D;}
| ^
/tmp/test.cpp:92:50: error: no matching function for call to 'dependent'
92 | [[clang::noinline]] return non_dependent(x) + (dependent<D>(x) + ...);
| ^~~~~~~~~~~~
/tmp/test.cpp:60:5: note: candidate template ignored: substitution failure [with D = 0]
60 | int dependent(int x){ return x + D;}
| ^
/tmp/test.cpp:92:23: warning: statement attribute 'clang::noinline' has higher precedence than function attribute 'always_inline' [-Wignored-attributes]
92 | [[clang::noinline]] return non_dependent(x) + (dependent<D>(x) + ...);
| ^
/tmp/test.cpp:63:1: note: conflicting attribute is here
63 | int non_dependent(int x){return x;}
| ^
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0. Program arguments: /usr/lib/llvm-22/bin/clang -cc1 -triple x86_64-pc-linux-gnu -emit-obj -dumpdir a- -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name test.cpp -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/home/fuzz/WorkSpace/fusion-fuzz/projects/clang -fcoverage-compilation-dir=/home/fuzz/WorkSpace/fusion-fuzz/projects/clang -resource-dir /usr/lib/llvm-22/lib/clang/22 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/15/../../../../include/c++/15 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/15/../../../../include/x86_64-linux-gnu/c++/15 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/15/../../../../include/c++/15/backward -internal-isystem /usr/lib/llvm-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/15/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdeprecated-macro -ferr<truncated>Please see the issue for the entire body.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs