https://github.com/cor3ntin updated 
https://github.com/llvm/llvm-project/pull/132091

>From 68ebbf821176dd17a757c32771fa728f21d4dd11 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinja...@gmail.com>
Date: Wed, 19 Mar 2025 21:05:38 +0100
Subject: [PATCH] [Clang] Fix UB in #131515

It turns out trailing objects are uninitialized
and APValue assignment operator requires a fully initialized object.
---
 clang/include/clang/AST/ExprCXX.h                    |  2 +-
 clang/lib/AST/ExprCXX.cpp                            | 12 ++++++++++--
 clang/lib/Sema/SemaDeclCXX.cpp                       |  4 ++--
 .../test/SemaCXX/builtin-structured-binding-size.cpp |  4 ++--
 4 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/clang/include/clang/AST/ExprCXX.h 
b/clang/include/clang/AST/ExprCXX.h
index 724ed437f1075..223d74993e9e6 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -2777,7 +2777,7 @@ class TypeTraitExpr final
                 ArrayRef<TypeSourceInfo *> Args, SourceLocation RParenLoc,
                 std::variant<bool, APValue> Value);
 
-  TypeTraitExpr(EmptyShell Empty) : Expr(TypeTraitExprClass, Empty) {}
+  TypeTraitExpr(EmptyShell Empty, bool IsStoredAsBool);
 
   size_t numTrailingObjects(OverloadToken<TypeSourceInfo *>) const {
     return getNumArgs();
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index c2cf4ffe506c6..a000e988e6834 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -1868,7 +1868,8 @@ TypeTraitExpr::TypeTraitExpr(QualType T, SourceLocation 
Loc, TypeTrait Kind,
   if (TypeTraitExprBits.IsBooleanTypeTrait)
     TypeTraitExprBits.Value = std::get<bool>(Value);
   else
-    *getTrailingObjects<APValue>() = std::get<APValue>(std::move(Value));
+    ::new (getTrailingObjects<APValue>())
+        APValue(std::get<APValue>(std::move(Value)));
 
   TypeTraitExprBits.NumArgs = Args.size();
   assert(Args.size() == TypeTraitExprBits.NumArgs &&
@@ -1884,6 +1885,13 @@ TypeTraitExpr::TypeTraitExpr(QualType T, SourceLocation 
Loc, TypeTrait Kind,
          "Only int values are supported by clang");
 }
 
+TypeTraitExpr::TypeTraitExpr(EmptyShell Empty, bool IsStoredAsBool)
+    : Expr(TypeTraitExprClass, Empty) {
+  TypeTraitExprBits.IsBooleanTypeTrait = IsStoredAsBool;
+  if (!IsStoredAsBool)
+    ::new (getTrailingObjects<APValue>()) APValue();
+}
+
 TypeTraitExpr *TypeTraitExpr::Create(const ASTContext &C, QualType T,
                                      SourceLocation Loc,
                                      TypeTrait Kind,
@@ -1909,7 +1917,7 @@ TypeTraitExpr *TypeTraitExpr::CreateDeserialized(const 
ASTContext &C,
                                                  unsigned NumArgs) {
   void *Mem = C.Allocate(totalSizeToAlloc<APValue, TypeSourceInfo *>(
       IsStoredAsBool ? 0 : 1, NumArgs));
-  return new (Mem) TypeTraitExpr(EmptyShell());
+  return new (Mem) TypeTraitExpr(EmptyShell(), IsStoredAsBool);
 }
 
 CUDAKernelCallExpr::CUDAKernelCallExpr(Expr *Fn, CallExpr *Config,
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index bd6321c46a78f..a1551e8027cd3 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -1681,7 +1681,7 @@ std::optional<unsigned> 
Sema::GetDecompositionElementCount(QualType T,
   llvm::APSInt TupleSize(Ctx.getTypeSize(Ctx.getSizeType()));
   switch (isTupleLike(*this, Loc, T, TupleSize)) {
   case IsTupleLike::Error:
-    return {};
+    return std::nullopt;
   case IsTupleLike::TupleLike:
     return TupleSize.getExtValue();
   case IsTupleLike::NotTupleLike:
@@ -1706,7 +1706,7 @@ std::optional<unsigned> 
Sema::GetDecompositionElementCount(QualType T,
       RD->fields(), [](FieldDecl *FD) { return !FD->isUnnamedBitField(); });
 
   if (CheckMemberDecompositionFields(*this, Loc, OrigRD, T, BasePair))
-    return true;
+    return std::nullopt;
 
   return NumFields;
 }
diff --git a/clang/test/SemaCXX/builtin-structured-binding-size.cpp 
b/clang/test/SemaCXX/builtin-structured-binding-size.cpp
index 85b1d81e08e33..53576048754ab 100644
--- a/clang/test/SemaCXX/builtin-structured-binding-size.cpp
+++ b/clang/test/SemaCXX/builtin-structured-binding-size.cpp
@@ -40,9 +40,9 @@ static_assert(__builtin_structured_binding_size(S5) == 2);
 // expected-error@-1 {{static assertion failed due to requirement 
'__builtin_structured_binding_size(S5) == 2'}} \
 // expected-note@-1 {{expression evaluates to '1 == 2'}}
 static_assert(__builtin_structured_binding_size(S6) == 2);
-// expected-error@-1 {{static assertion failed due to requirement 
'__builtin_structured_binding_size(S6) == 2'}} \
 // expected-error@-1 {{cannot decompose class type 'S6' because it has an 
anonymous union member}} \
-// expected-note@-1 {{expression evaluates to '1 == 2'}}
+// expected-error@-1 {{type 'S6' cannot be decomposed}} \
+// expected-error@-1 {{static assertion expression is not an integral constant 
expression}} \
 // expected-note@#note-anon-union {{declared here}}
 static_assert(__builtin_structured_binding_size(S7) == 1);
 

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to