yonghong-song created this revision.
yonghong-song added reviewers: compnerd, aaron.ballman.
Herald added a project: All.
yonghong-song requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

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


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D126223

Files:
  clang/lib/Sema/SemaType.cpp
  clang/test/Sema/atomic-typeof.c


Index: clang/test/Sema/atomic-typeof.c
===================================================================
--- /dev/null
+++ clang/test/Sema/atomic-typeof.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c11 -x c %s
+
+struct dispatch_object_s;
+void _dispatch_queue_get_head(struct dispatch_object_s * volatile 
dq_items_head) {
+  (_Atomic __typeof__(dq_items_head) *)dq_items_head;
+}
Index: clang/lib/Sema/SemaType.cpp
===================================================================
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -6109,7 +6109,8 @@
         TL.setArgLocInfo(I, TemplateArgsInfo.arguments()[I].getLocInfo());
     }
     void VisitTagTypeLoc(TagTypeLoc TL) {
-      TL.setNameLoc(DS.getTypeSpecTypeNameLoc());
+      if (DS.getTypeSpecType() != DeclSpec::TST_typeofExpr)
+        TL.setNameLoc(DS.getTypeSpecTypeNameLoc());
     }
     void VisitAtomicTypeLoc(AtomicTypeLoc TL) {
       // An AtomicTypeLoc can come from either an _Atomic(...) type specifier


Index: clang/test/Sema/atomic-typeof.c
===================================================================
--- /dev/null
+++ clang/test/Sema/atomic-typeof.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c11 -x c %s
+
+struct dispatch_object_s;
+void _dispatch_queue_get_head(struct dispatch_object_s * volatile dq_items_head) {
+  (_Atomic __typeof__(dq_items_head) *)dq_items_head;
+}
Index: clang/lib/Sema/SemaType.cpp
===================================================================
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -6109,7 +6109,8 @@
         TL.setArgLocInfo(I, TemplateArgsInfo.arguments()[I].getLocInfo());
     }
     void VisitTagTypeLoc(TagTypeLoc TL) {
-      TL.setNameLoc(DS.getTypeSpecTypeNameLoc());
+      if (DS.getTypeSpecType() != DeclSpec::TST_typeofExpr)
+        TL.setNameLoc(DS.getTypeSpecTypeNameLoc());
     }
     void VisitAtomicTypeLoc(AtomicTypeLoc TL) {
       // An AtomicTypeLoc can come from either an _Atomic(...) type specifier
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D126223: [Clang][Sem... Yonghong Song via Phabricator via cfe-commits

Reply via email to