// RUN: not %clang -O2 -fdiagnostics-show-inlining-chain -S %s -o /dev/null 2>&1 | FileCheck %s // Single-level inlining with warning attribute. [[gnu::warning("do not call directly")]] void __warn_single(void); static inline void warn_wrapper(void) { __warn_single(); } void test_single_level(void) { warn_wrapper(); } // CHECK: warning: call to '__warn_single' declared with 'warning' attribute: do not call directly // CHECK: note: called by function 'warn_wrapper' // CHECK: :12:{{.*}}: note: inlined by function 'test_single_level' // Error attribute with inlining. [[gnu::error("never call this")]] void __error_func(void); static inline void error_wrapper(void) { __error_func(); } void test_error_inlined(void) { error_wrapper(); } // CHECK: error: call to '__error_func' declared with 'error' attribute: never call this // CHECK: note: called by function 'error_wrapper' // CHECK: :27:{{.*}}: note: inlined by function 'test_error_inlined' // Deep nesting (5 levels). [[gnu::warning("deep call")]] void __warn_deep(void); static inline void deep1(void) { __warn_deep(); } static inline void deep2(void) { deep1(); } static inline void deep3(void) { deep2(); } static inline void deep4(void) { deep3(); } static inline void deep5(void) { deep4(); } void test_deep_nesting(void) { deep5(); } // CHECK: warning: call to '__warn_deep' declared with 'warning' attribute: deep call // CHECK: note: called by function 'deep1' // CHECK: :38:{{.*}}: note: inlined by function 'deep2' // CHECK: :39:{{.*}}: note: inlined by function 'deep3' // CHECK: :40:{{.*}}: note: inlined by function 'deep4' // CHECK: :41:{{.*}}: note: inlined by function 'deep5' // CHECK: :44:{{.*}}: note: inlined by function 'test_deep_nesting' // Multiple call sites produce distinct diagnostics. [[gnu::warning("deprecated")]] void __warn_multi(void); static inline void multi_wrapper(void) { __warn_multi(); } void call_site_a(void) { multi_wrapper(); } void call_site_b(void) { multi_wrapper(); } void call_site_c(void) { multi_wrapper(); } // CHECK: warning: call to '__warn_multi' declared with 'warning' attribute: deprecated // CHECK: note: called by function 'multi_wrapper' // CHECK: :62:{{.*}}: note: inlined by function 'call_site_a' // CHECK: warning: call to '__warn_multi' declared with 'warning' attribute: deprecated // CHECK: note: called by function 'multi_wrapper' // CHECK: :63:{{.*}}: note: inlined by function 'call_site_b' // CHECK: warning: call to '__warn_multi' declared with 'warning' attribute: deprecated // CHECK: note: called by function 'multi_wrapper' // CHECK: :64:{{.*}}: note: inlined by function 'call_site_c' // Different nesting depths from same inner function. [[gnu::warning("mixed depth")]] void __warn_mixed(void); static inline void mixed_inner(void) { __warn_mixed(); } static inline void mixed_middle(void) { mixed_inner(); } void shallow(void) { mixed_inner(); } void deep(void) { mixed_middle(); } // CHECK: warning: call to '__warn_mixed' declared with 'warning' attribute: mixed depth // CHECK: note: called by function 'mixed_inner' // CHECK: :85:{{.*}}: note: inlined by function 'shallow' // CHECK: warning: call to '__warn_mixed' declared with 'warning' attribute: mixed depth // CHECK: note: called by function 'mixed_inner' // CHECK: :83:{{.*}}: note: inlined by function 'mixed_middle' // CHECK: :86:{{.*}}: note: inlined by function 'deep' // Incidental inlining (function not marked inline/static). // The "inlined by" note has no location since heuristic mode doesn't track it. [[gnu::warning("incidental")]] void __warn_incidental(void); void not_marked_inline(void) { __warn_incidental(); } void test_incidental(void) { not_marked_inline(); } // CHECK: warning: call to '__warn_incidental' declared with 'warning' attribute: incidental // CHECK: note: called by function 'not_marked_inline' // CHECK: note: inlined by function 'test_incidental' // CHECK-NOT: :{{.*}}: note: inlined by function 'test_incidental' // Fallback note should appear (no debug info). // CHECK: note: use '-gline-directives-only' (implied by '-g1') or higher for more accurate inlining chain locations