[clang] e4f1ef8 - [clang][Interp] Reject bitcasts to atomic types

Timm Bäder via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 5 06:45:37 PST 2024


Author: Timm Bäder
Date: 2024-02-05T15:45:26+01:00
New Revision: e4f1ef85fd60c08c9ece4982fccf76e8101011b8

URL: https://github.com/llvm/llvm-project/commit/e4f1ef85fd60c08c9ece4982fccf76e8101011b8
DIFF: https://github.com/llvm/llvm-project/commit/e4f1ef85fd60c08c9ece4982fccf76e8101011b8.diff

LOG: [clang][Interp] Reject bitcasts to atomic types

The current interpreter does this, so follow suit to match its
diagnostics.

Added: 
    clang/test/AST/Interp/atomic.c

Modified: 
    clang/lib/AST/Interp/ByteCodeExprGen.cpp
    clang/lib/AST/Interp/Interp.h
    clang/lib/AST/Interp/PrimType.h
    clang/test/Sema/atomic-expr.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 3ca4f56903fda0..74a5284ff812cf 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -191,7 +191,14 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
   case CK_NonAtomicToAtomic:
   case CK_NoOp:
   case CK_UserDefinedConversion:
+    return this->delegate(SubExpr);
+
   case CK_BitCast:
+    if (CE->getType()->isAtomicType()) {
+      if (!this->discard(SubExpr))
+        return false;
+      return this->emitInvalidCast(CastKind::Reinterpret, CE);
+    }
     return this->delegate(SubExpr);
 
   case CK_IntegralToBoolean:

diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 7c7e53564c4b49..e41604e125eba6 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -2020,8 +2020,11 @@ inline bool Invalid(InterpState &S, CodePtr OpPC) {
 /// Same here, but only for casts.
 inline bool InvalidCast(InterpState &S, CodePtr OpPC, CastKind Kind) {
   const SourceLocation &Loc = S.Current->getLocation(OpPC);
-  S.FFDiag(Loc, diag::note_constexpr_invalid_cast)
-      << static_cast<unsigned>(Kind) << S.Current->getRange(OpPC);
+
+  // FIXME: Support diagnosing other invalid cast kinds.
+  if (Kind == CastKind::Reinterpret)
+    S.FFDiag(Loc, diag::note_constexpr_invalid_cast)
+        << static_cast<unsigned>(Kind) << S.Current->getRange(OpPC);
   return false;
 }
 

diff  --git a/clang/lib/AST/Interp/PrimType.h b/clang/lib/AST/Interp/PrimType.h
index 8c5e87f37be186..d07c2efe8e3c9b 100644
--- a/clang/lib/AST/Interp/PrimType.h
+++ b/clang/lib/AST/Interp/PrimType.h
@@ -48,6 +48,7 @@ enum PrimType : unsigned {
 
 enum class CastKind : uint8_t {
   Reinterpret,
+  Atomic,
 };
 inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
                                      interp::CastKind CK) {
@@ -55,6 +56,9 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
   case interp::CastKind::Reinterpret:
     OS << "reinterpret_cast";
     break;
+  case interp::CastKind::Atomic:
+    OS << "atomic";
+    break;
   }
   return OS;
 }

diff  --git a/clang/test/AST/Interp/atomic.c b/clang/test/AST/Interp/atomic.c
new file mode 100644
index 00000000000000..8d93b57c1945bc
--- /dev/null
+++ b/clang/test/AST/Interp/atomic.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=both,expected %s
+// RUN: %clang_cc1 -verify=both,ref %s
+
+/// FIXME: Copied from test/Sema/atomic-expr.c.
+/// this expression seems to be rejected for weird reasons,
+/// but we imitate the current interpreter's behavior.
+_Atomic int ai = 0;
+// FIXME: &ai is an address constant, so this should be accepted as an
+// initializer, but the bit-cast inserted due to the pointer conversion is
+// tripping up the test for whether the initializer is a constant expression.
+// The warning is correct but the error is not.
+_Atomic(int *) aip3 = &ai; // both-warning {{incompatible pointer types initializing '_Atomic(int *)' with an expression of type '_Atomic(int) *'}} \
+                           // both-error {{initializer element is not a compile-time constant}}

diff  --git a/clang/test/Sema/atomic-expr.c b/clang/test/Sema/atomic-expr.c
index 8eefbf92152b81..7e5219dd3f14ab 100644
--- a/clang/test/Sema/atomic-expr.c
+++ b/clang/test/Sema/atomic-expr.c
@@ -2,6 +2,11 @@
 // RUN: %clang_cc1 %s -std=c2x -verify=expected,access -fsyntax-only
 // RUN: %clang_cc1 %s -std=c2x -pedantic -verify=expected,access -fsyntax-only
 // RUN: %clang_cc1 %s -verify -fsyntax-only -Wno-atomic-access
+// RUN: %clang_cc1 %s -verify=expected,access -fsyntax-only -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 %s -std=c2x -verify=expected,access -fsyntax-only -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 %s -std=c2x -pedantic -verify=expected,access -fsyntax-only -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Wno-atomic-access -fexperimental-new-constant-interpreter
+
 
 _Atomic(unsigned int) data1;
 int _Atomic data2;


        


More information about the cfe-commits mailing list