Patch [1] added btf_type_tag attribute support. In particular,
in class TypeSpecLocFiller, it permitted to visit pointee's
of a PointerTypeLoc. This caused a behavior change outside
of the btf_type_tag area. Saleem Abdulrasool reported that
assertion would happen for the following code:
struct dispatch_object_s;
void *_dispatch_queue_get_head(struct dispatch_object_s * volatile dq_items_head) {
return (void *)(_Atomic __typeof__(dq_items_head) *)dq_items_head;
}
The following is what happened:
... 1. In Parse/ParseDecl.cpp, ParseTypeofSpecifier() is called to handle typeof specifier. DeclSpec is set to TST_typeofExpr. 2. Later, in Sema/SemaType.cpp, TypeSpecLocFiller(S, S.Context, State, D.getDeclSpec()).Visit(CurrTL) is called. 3. The specific types visited in the following order: VisitAtomicTypeLoc() VisitPointerTypeLoc() VisitElaboratedTypeLo()c VisitTagTypeLoc()
During VisitTagTypeLoc(), since DeclSpec is TST_typeofExpr, this will cause
assertion error in DS.getTypeSpecTypeNameLoc().
clang: /home/yhs/work/llvm-project/clang/include/clang/Sema/DeclSpec.h:519: clang::SourceLocation clang::DeclSpec::getTypeSpecTypeNameLoc() const: Assertion `isDeclRep((TST) TypeSpecType) || TypeSpecType == TST_typename' failed.
If we remove the _Atomic in the above code like
struct dispatch_object_s;
void *_dispatch_queue_get_head(struct dispatch_object_s * volatile dq_items_head) {
return (void *)(_Atomic __typeof__(dq_items_head) *)dq_items_head;
}
The above step 3 will have VisitTypeOfExprTypeLoc() and no assertion happens.
To fix the issue, in VisitTagTypeLoc(), let us not do DS.getTypeSpecTypeNameLoc()
if the DeclSpec is TST_typeofExpr.
[1] https://reviews.llvm.org/D111199