Missing NoReturnAttr in the AST?

Hi,

Having a source file (/tmp/attr.cpp)
void f() attribute((analyzer_noreturn));
void g() attribute((noreturn));
[[gnu::noreturn]] void h(void);

Generates the following AST, when clang -cc1 -ast-dump /tmp/attr.cpp is used

-FunctionDecl 0x18a5178 </tmp/attr.cpp:1:1, col:43> col:6 f ‘void ()’
-AnalyzerNoReturnAttr 0x18a5218 <col:25> -FunctionDecl 0x18a5308 <line:2:1, col:34> col:6 g 'void () __attribute__((noreturn))' -FunctionDecl 0x18a5440 <line:3:19, col:30> col:24 h ‘void () attribute((noreturn))’

I.e. the NoReturnAttr node is missing. This is very confusing, when compared to the AnalyzerNoReturnAttr, which is there.
The only difference in Attr.td is that noreturn has GCC spelling, while analyzer_noreturn has GNU spelling.
What am I missing to have a NoReturnAttr node? Do I have to specify a special extra flag for CC1 to enable GCC attributes?

Thanks,
Gabor

I’ve found that the GCC attribute((noreturn)) is part of the type, and not parsed into a separate AST node like the C++11 [[noreturn]] or the GNU attribute((analyzer_noreturn)).
To query the GCC attribute((noreturn)) we can use FunctionType::getNoReturnAttr().

Why do we have these differences, with these attributes, why was the GCC noreturn uplifted into the Type?

Thanks,
Gabor

I’ve found that the GCC attribute((noreturn)) is part of the type, and not parsed into a separate AST node like the C++11 [[noreturn]] or the GNU attribute((analyzer_noreturn)).
To query the GCC attribute((noreturn)) we can use FunctionType::getNoReturnAttr().

Why do we have these differences, with these attributes, why was the GCC noreturn uplifted into the Type?

Because it applies to function types:
typedef void (*fptype)(void) attribute((noreturn));
int f(int x, fptype fp) {
if (x) return 42;
fp();
}

I’ve found that the GCC attribute((noreturn)) is part of the type, and not parsed into a separate AST node like the C++11 [[noreturn]] or the GNU attribute((analyzer_noreturn)).
To query the GCC attribute((noreturn)) we can use FunctionType::getNoReturnAttr().

Why do we have these differences, with these attributes, why was the GCC noreturn uplifted into the Type?

Because it applies to function types:
typedef void (*fptype)(void) attribute((noreturn));
int f(int x, fptype fp) {
if (x) return 42;
fp();
}

Yes. We are missing the AttributedType node in the AST in this case, though:

typedef void (*fptype)(void) attribute((noreturn));
#pragma clang __debug dump fptype;

gives:

TypedefDecl 0x55822b34e048 <:1:1, col:28> col:16 fptype ‘void (*)() attribute((noreturn))’
-PointerType 0x55822b34dff0 'void (*)() __attribute__((noreturn))' -ParenType 0x55822b34df90 ‘void () attribute((noreturn))’ sugar
-FunctionProtoType 0x55822b34df60 'void () __attribute__((noreturn))' noreturn cdecl -BuiltinType 0x55822b30b7e0 ‘void’

Consider for comparison

typedef int *attribute((address_space(3))) *p;
#pragma clang __debug dump p;

which gives:

TypedefDecl 0x5619f0bc2f90 <:1:1, col:49> col:49 p ‘int *attribute((address_space(3))) *’
-PointerType 0x5619f0bc2f40 'int *__attribute__((address_space(3))) *' -AttributedType 0x5619f0bc2ee0 ‘int *attribute((address_space(3)))’ sugar

-PointerType 0x5619f0bc2e70 ‘int *’
-BuiltinType 0x5619f0b80880 'int' -QualType 0x5619f0bc2ec8 ‘int *attribute((address_space(3)))’ attribute((address_space(3)))
-PointerType 0x5619f0bc2e70 'int *' -BuiltinType 0x5619f0b80880 ‘int’

(The reason for this is that support for noreturn long predates AttributedType and we forgot to update the relevant code to produce the AttributedType wrapper.)