File tree Expand file tree Collapse file tree 3 files changed +28
-4
lines changed Expand file tree Collapse file tree 3 files changed +28
-4
lines changed Original file line number Diff line number Diff line change 22_Noreturn void f (void );
33__attribute__ ((noreturn)) void g(void );
44[[noreturn]] void h (void );
5+ void i (__attribute__((noreturn)) void (*arg)(void ));
6+ __attribute__ ((noreturn)) void j(__attribute__((noreturn)) void (*arg)(void ));
Original file line number Diff line number Diff line change @@ -505,10 +505,24 @@ impl FunctionSig {
505505 Default :: default ( )
506506 } ;
507507
508- // This looks easy to break but the clang parser keeps the type spelling clean even if
509- // other attributes are added.
510- is_divergent =
511- is_divergent || ty. spelling ( ) . contains ( "__attribute__((noreturn))" ) ;
508+ // Check if the type contains __attribute__((noreturn)) outside of parentheses. This is
509+ // somewhat fragile, but it seems to be the only way to get at this information as of
510+ // libclang 9.
511+ let ty_spelling = ty. spelling ( ) ;
512+ let has_attribute_noreturn = ty_spelling
513+ . match_indices ( "__attribute__((noreturn))" )
514+ . any ( |( i, _) | {
515+ let depth = ty_spelling[ ..i]
516+ . bytes ( )
517+ . filter_map ( |ch| match ch {
518+ b'(' => Some ( 1 ) ,
519+ b')' => Some ( -1 ) ,
520+ _ => None ,
521+ } )
522+ . sum :: < isize > ( ) ;
523+ depth == 0
524+ } ) ;
525+ is_divergent = is_divergent || has_attribute_noreturn;
512526
513527 let is_method = kind == CXCursor_CXXMethod ;
514528 let is_constructor = kind == CXCursor_Constructor ;
You can’t perform that action at this time.
0 commit comments