[clang] No longer assert when using noderef on an _Atomic type (PR #116237)
Aaron Ballman via cfe-commits
cfe-commits at lists.llvm.org
Thu Nov 14 06:53:27 PST 2024
https://github.com/AaronBallman updated https://github.com/llvm/llvm-project/pull/116237
>From c46fabd4d9bd1dd8061c5500693a31cde2382b8c Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Thu, 14 Nov 2024 09:18:24 -0500
Subject: [PATCH 1/2] No longer assert when using noderef on an _Atomic type
Fixes #116124
---
clang/docs/ReleaseNotes.rst | 2 ++
clang/lib/Sema/SemaType.cpp | 51 +++++++++++++++++----------------
clang/test/Frontend/noderef.cpp | 6 ++++
3 files changed, 35 insertions(+), 24 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 3fc275b528d215..0c29e99c72481c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -553,6 +553,8 @@ Bug Fixes in This Version
the unsupported type instead of the ``register`` keyword (#GH109776).
- Fixed a crash when emit ctor for global variant with flexible array init (#GH113187).
- Fixed a crash when GNU statement expression contains invalid statement (#GH113468).
+- Fixed a failed assertion when using ``__attribute__((noderef))`` on an
+ ``_Atomic``-qualified type (#GH116124).
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index dd7c438cbd33ec..4fac71ba095668 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -5837,6 +5837,30 @@ static void fillMatrixTypeLoc(MatrixTypeLoc MTL,
llvm_unreachable("no matrix_type attribute found at the expected location!");
}
+static void fillAtomicQualLoc(AtomicTypeLoc ATL, const DeclaratorChunk &Chunk) {
+ SourceLocation Loc;
+ switch (Chunk.Kind) {
+ case DeclaratorChunk::Function:
+ case DeclaratorChunk::Array:
+ case DeclaratorChunk::Paren:
+ case DeclaratorChunk::Pipe:
+ llvm_unreachable("cannot be _Atomic qualified");
+
+ case DeclaratorChunk::Pointer:
+ Loc = Chunk.Ptr.AtomicQualLoc;
+ break;
+
+ case DeclaratorChunk::BlockPointer:
+ case DeclaratorChunk::Reference:
+ case DeclaratorChunk::MemberPointer:
+ // FIXME: Provide a source location for the _Atomic keyword.
+ break;
+ }
+
+ ATL.setKWLoc(Loc);
+ ATL.setParensRange(SourceRange());
+}
+
namespace {
class TypeSpecLocFiller : public TypeLocVisitor<TypeSpecLocFiller> {
Sema &SemaRef;
@@ -6223,6 +6247,9 @@ namespace {
void VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
TL.setNameLoc(Chunk.Loc);
}
+ void VisitAtomicTypeLoc(AtomicTypeLoc TL) {
+ fillAtomicQualLoc(TL, Chunk);
+ }
void
VisitDependentSizedExtVectorTypeLoc(DependentSizedExtVectorTypeLoc TL) {
TL.setNameLoc(Chunk.Loc);
@@ -6237,30 +6264,6 @@ namespace {
};
} // end anonymous namespace
-static void fillAtomicQualLoc(AtomicTypeLoc ATL, const DeclaratorChunk &Chunk) {
- SourceLocation Loc;
- switch (Chunk.Kind) {
- case DeclaratorChunk::Function:
- case DeclaratorChunk::Array:
- case DeclaratorChunk::Paren:
- case DeclaratorChunk::Pipe:
- llvm_unreachable("cannot be _Atomic qualified");
-
- case DeclaratorChunk::Pointer:
- Loc = Chunk.Ptr.AtomicQualLoc;
- break;
-
- case DeclaratorChunk::BlockPointer:
- case DeclaratorChunk::Reference:
- case DeclaratorChunk::MemberPointer:
- // FIXME: Provide a source location for the _Atomic keyword.
- break;
- }
-
- ATL.setKWLoc(Loc);
- ATL.setParensRange(SourceRange());
-}
-
static void
fillDependentAddressSpaceTypeLoc(DependentAddressSpaceTypeLoc DASTL,
const ParsedAttributesView &Attrs) {
diff --git a/clang/test/Frontend/noderef.cpp b/clang/test/Frontend/noderef.cpp
index 68342a8e6467b8..048f80cd809474 100644
--- a/clang/test/Frontend/noderef.cpp
+++ b/clang/test/Frontend/noderef.cpp
@@ -183,3 +183,9 @@ int *const_cast_check(NODEREF const int *x) {
const int *const_cast_check(NODEREF int *x) {
return const_cast<const int *>(x); // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
}
+
+namespace GH116124 {
+// This declaration would previously cause a failed assertion.
+int *_Atomic a __attribute__((noderef)); // expected-note {{declared here}}
+int x = *a; // expected-warning{{dereferencing a; was declared with a 'noderef' type}}
+}
>From 588ba0911c69591ccfaf9d7edbb9521952ec7af5 Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Thu, 14 Nov 2024 09:51:45 -0500
Subject: [PATCH 2/2] Fixing an invalid test
Putting the attribute after the declarator has different behavior than
putting it before or on the type itself; the expected diagnostics were
not triggered.
This was caught by precommit CI. My local testing did not catch it
because I was accidentally testing noderef.c instead of noderef.cpp.
This removes the expected diagnostics and just leaves in the "does not
crash" test.
---
clang/test/Frontend/noderef.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/clang/test/Frontend/noderef.cpp b/clang/test/Frontend/noderef.cpp
index 048f80cd809474..44c11da0dc56a0 100644
--- a/clang/test/Frontend/noderef.cpp
+++ b/clang/test/Frontend/noderef.cpp
@@ -186,6 +186,5 @@ const int *const_cast_check(NODEREF int *x) {
namespace GH116124 {
// This declaration would previously cause a failed assertion.
-int *_Atomic a __attribute__((noderef)); // expected-note {{declared here}}
-int x = *a; // expected-warning{{dereferencing a; was declared with a 'noderef' type}}
+int *_Atomic a __attribute__((noderef));
}
More information about the cfe-commits
mailing list