[clang] 107fe0e - [clang][bytecode] Fix a crash in CheckConstantExpression (#129752)

via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 4 23:21:55 PST 2025


Author: Timm Baeder
Date: 2025-03-05T08:21:51+01:00
New Revision: 107fe0ec6cb36dca6bfafbfdf2996ce38d84e5bd

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

LOG: [clang][bytecode] Fix a crash in CheckConstantExpression (#129752)

The APValue we generated for a pointer with a LValueReferenceType base
had an incorrect lvalue path attached.

The attached test case is extracted from libc++'s regex.cpp.

Added: 
    

Modified: 
    clang/lib/AST/ByteCode/Pointer.cpp
    clang/test/AST/ByteCode/references.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ByteCode/Pointer.cpp b/clang/lib/AST/ByteCode/Pointer.cpp
index 324097a95dda3..8abdc54b64677 100644
--- a/clang/lib/AST/ByteCode/Pointer.cpp
+++ b/clang/lib/AST/ByteCode/Pointer.cpp
@@ -210,7 +210,8 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const {
   };
 
   bool UsePath = true;
-  if (getType()->isLValueReferenceType())
+  if (const ValueDecl *VD = getDeclDesc()->asValueDecl();
+      VD && VD->getType()->isLValueReferenceType())
     UsePath = false;
 
   // Build the path into the object.

diff  --git a/clang/test/AST/ByteCode/references.cpp b/clang/test/AST/ByteCode/references.cpp
index 7610655958230..36609b7df3f59 100644
--- a/clang/test/AST/ByteCode/references.cpp
+++ b/clang/test/AST/ByteCode/references.cpp
@@ -140,3 +140,41 @@ namespace Temporaries {
   static_assert(j.a.n == 1, "");  // both-error {{not an integral constant expression}} \
                                   // both-note {{read of temporary is not allowed in a constant expression outside the expression that created the temporary}}
 }
+
+namespace Params {
+  typedef __SIZE_TYPE__ size_t;
+
+  template <class _Tp, size_t _Np>
+  constexpr _Tp* end(_Tp (&__array)[_Np]) noexcept {
+    return __array + _Np;
+  }
+
+
+  struct classnames {
+    const char* elem_;
+    int a;
+  };
+
+  constexpr classnames ClassNames[] = {
+    {"a", 0},
+    {"b", 1},
+    {"b", 1},
+    {"b", 1},
+    {"b", 1},
+    {"b", 1},
+    {"b", 1},
+    {"b", 1},
+  };
+
+  constexpr bool foo() {
+    /// This will instantiate end() with ClassNames.
+    /// In Sema, we will constant-evaluate the return statement, which is
+    /// something like __array + 8. The APValue we return for this
+    /// may NOT have a LValuePath set, since it's for a parameter
+    /// of LValueReferenceType.
+    end(ClassNames);
+    return true;
+  }
+
+  static_assert(foo());
+}


        


More information about the cfe-commits mailing list