Skip to content

Commit 75073a8

Browse files
committed
[AutoBump] Merge with 21ba91c (Jun 17)
2 parents 86fd3f7 + 21ba91c commit 75073a8

File tree

96 files changed

+9050
-3912
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+9050
-3912
lines changed

.github/workflows/pr-code-format.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ jobs:
5454
- name: Install clang-format
5555
uses: aminya/setup-cpp@v1
5656
with:
57-
clangformat: 18.1.1
57+
clangformat: 18.1.7
5858

5959
- name: Setup Python env
6060
uses: actions/setup-python@v5

clang/docs/ReleaseNotes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,9 @@ Resolutions to C++ Defect Reports
268268
- Clang now requires a template argument list after a template keyword.
269269
(`CWG96: Syntactic disambiguation using the template keyword <https://cplusplus.github.io/CWG/issues/96.html>`_).
270270

271+
- Clang now considers ``noexcept(typeid(expr))`` more carefully, instead of always assuming that ``std::bad_typeid`` can be thrown.
272+
(`CWG2191: Incorrect result for noexcept(typeid(v)) <https://cplusplus.github.io/CWG/issues/2191.html>`_).
273+
271274
C Language Changes
272275
------------------
273276

@@ -859,6 +862,8 @@ Bug Fixes to C++ Support
859862
(#GH88081), (#GH89496), (#GH90669) and (#GH91633).
860863
- Fixed handling of brace ellison when building deduction guides. (#GH64625), (#GH83368).
861864
- Clang now instantiates local constexpr functions eagerly for constant evaluators. (#GH35052), (#GH94849)
865+
- Fixed a failed assertion when attempting to convert an integer representing the difference
866+
between the addresses of two labels (a GNU extension) to a pointer within a constant expression. (#GH95366).
862867

863868
Bug Fixes to AST Handling
864869
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/include/clang/AST/ExprCXX.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,10 @@ class CXXTypeidExpr : public Expr {
919919
reinterpret_cast<Stmt **>(&const_cast<CXXTypeidExpr *>(this)->Operand);
920920
return const_child_range(begin, begin + 1);
921921
}
922+
923+
/// Whether this is of a form like "typeid(*ptr)" that can throw a
924+
/// std::bad_typeid if a pointer is a null pointer ([expr.typeid]p2)
925+
bool hasNullCheck() const;
922926
};
923927

924928
/// A member reference to an MSPropertyDecl.

clang/include/clang/Driver/Options.td

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7036,6 +7036,12 @@ def as_secure_log_file : Separate<["-"], "as-secure-log-file">,
70367036

70377037
} // let Visibility = [CC1Option, CC1AsOption]
70387038

7039+
let Visibility = [CC1Option, FC1Option] in {
7040+
def mlink_builtin_bitcode : Separate<["-"], "mlink-builtin-bitcode">,
7041+
HelpText<"Link and internalize needed symbols from the given bitcode file "
7042+
"before performing optimizations.">;
7043+
} // let Visibility = [CC1Option, FC1Option]
7044+
70397045
let Visibility = [CC1Option] in {
70407046

70417047
def llvm_verify_each : Flag<["-"], "llvm-verify-each">,
@@ -7138,9 +7144,6 @@ defm constructor_aliases : BoolMOption<"constructor-aliases",
71387144
" emitting complete constructors and destructors as aliases when possible">>;
71397145
def mlink_bitcode_file : Separate<["-"], "mlink-bitcode-file">,
71407146
HelpText<"Link the given bitcode file before performing optimizations.">;
7141-
def mlink_builtin_bitcode : Separate<["-"], "mlink-builtin-bitcode">,
7142-
HelpText<"Link and internalize needed symbols from the given bitcode file "
7143-
"before performing optimizations.">;
71447147
defm link_builtin_bitcode_postopt: BoolMOption<"link-builtin-bitcode-postopt",
71457148
CodeGenOpts<"LinkBitcodePostopt">, DefaultFalse,
71467149
PosFlag<SetTrue, [], [ClangOption], "Link builtin bitcodes after the "

clang/lib/AST/Expr.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3769,10 +3769,18 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
37693769
break;
37703770
}
37713771

3772-
case CXXTypeidExprClass:
3773-
// typeid might throw if its subexpression is potentially-evaluated, so has
3774-
// side-effects in that case whether or not its subexpression does.
3775-
return cast<CXXTypeidExpr>(this)->isPotentiallyEvaluated();
3772+
case CXXTypeidExprClass: {
3773+
const auto *TE = cast<CXXTypeidExpr>(this);
3774+
if (!TE->isPotentiallyEvaluated())
3775+
return false;
3776+
3777+
// If this type id expression can throw because of a null pointer, that is a
3778+
// side-effect independent of if the operand has a side-effect
3779+
if (IncludePossibleEffects && TE->hasNullCheck())
3780+
return true;
3781+
3782+
break;
3783+
}
37763784

37773785
case CXXConstructExprClass:
37783786
case CXXTemporaryObjectExprClass: {

clang/lib/AST/ExprCXX.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,53 @@ QualType CXXTypeidExpr::getTypeOperand(ASTContext &Context) const {
166166
Operand.get<TypeSourceInfo *>()->getType().getNonReferenceType(), Quals);
167167
}
168168

169+
static bool isGLValueFromPointerDeref(const Expr *E) {
170+
E = E->IgnoreParens();
171+
172+
if (const auto *CE = dyn_cast<CastExpr>(E)) {
173+
if (!CE->getSubExpr()->isGLValue())
174+
return false;
175+
return isGLValueFromPointerDeref(CE->getSubExpr());
176+
}
177+
178+
if (const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
179+
return isGLValueFromPointerDeref(OVE->getSourceExpr());
180+
181+
if (const auto *BO = dyn_cast<BinaryOperator>(E))
182+
if (BO->getOpcode() == BO_Comma)
183+
return isGLValueFromPointerDeref(BO->getRHS());
184+
185+
if (const auto *ACO = dyn_cast<AbstractConditionalOperator>(E))
186+
return isGLValueFromPointerDeref(ACO->getTrueExpr()) ||
187+
isGLValueFromPointerDeref(ACO->getFalseExpr());
188+
189+
// C++11 [expr.sub]p1:
190+
// The expression E1[E2] is identical (by definition) to *((E1)+(E2))
191+
if (isa<ArraySubscriptExpr>(E))
192+
return true;
193+
194+
if (const auto *UO = dyn_cast<UnaryOperator>(E))
195+
if (UO->getOpcode() == UO_Deref)
196+
return true;
197+
198+
return false;
199+
}
200+
201+
bool CXXTypeidExpr::hasNullCheck() const {
202+
if (!isPotentiallyEvaluated())
203+
return false;
204+
205+
// C++ [expr.typeid]p2:
206+
// If the glvalue expression is obtained by applying the unary * operator to
207+
// a pointer and the pointer is a null pointer value, the typeid expression
208+
// throws the std::bad_typeid exception.
209+
//
210+
// However, this paragraph's intent is not clear. We choose a very generous
211+
// interpretation which implores us to consider comma operators, conditional
212+
// operators, parentheses and other such constructs.
213+
return isGLValueFromPointerDeref(getExprOperand());
214+
}
215+
169216
QualType CXXUuidofExpr::getTypeOperand(ASTContext &Context) const {
170217
assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)");
171218
Qualifiers Quals;

clang/lib/AST/ExprConstShared.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
#ifndef LLVM_CLANG_LIB_AST_EXPRCONSTSHARED_H
1515
#define LLVM_CLANG_LIB_AST_EXPRCONSTSHARED_H
1616

17+
namespace llvm {
18+
class APFloat;
19+
}
1720
namespace clang {
1821
class QualType;
1922
class LangOptions;
@@ -56,4 +59,8 @@ enum class GCCTypeClass {
5659
GCCTypeClass EvaluateBuiltinClassifyType(QualType T,
5760
const LangOptions &LangOpts);
5861

62+
void HandleComplexComplexMul(llvm::APFloat A, llvm::APFloat B, llvm::APFloat C,
63+
llvm::APFloat D, llvm::APFloat &ResR,
64+
llvm::APFloat &ResI);
65+
5966
#endif

clang/lib/AST/ExprConstant.cpp

Lines changed: 64 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -9325,6 +9325,13 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr *E) {
93259325
Result.IsNullPtr = false;
93269326
return true;
93279327
} else {
9328+
// In rare instances, the value isn't an lvalue.
9329+
// For example, when the value is the difference between the addresses of
9330+
// two labels. We reject that as a constant expression because we can't
9331+
// compute a valid offset to convert into a pointer.
9332+
if (!Value.isLValue())
9333+
return false;
9334+
93289335
// Cast is of an lvalue, no need to change value.
93299336
Result.setFrom(Info.Ctx, Value);
93309337
return true;
@@ -15126,6 +15133,62 @@ bool ComplexExprEvaluator::VisitCastExpr(const CastExpr *E) {
1512615133
llvm_unreachable("unknown cast resulting in complex value");
1512715134
}
1512815135

15136+
void HandleComplexComplexMul(APFloat A, APFloat B, APFloat C, APFloat D,
15137+
APFloat &ResR, APFloat &ResI) {
15138+
// This is an implementation of complex multiplication according to the
15139+
// constraints laid out in C11 Annex G. The implementation uses the
15140+
// following naming scheme:
15141+
// (a + ib) * (c + id)
15142+
15143+
APFloat AC = A * C;
15144+
APFloat BD = B * D;
15145+
APFloat AD = A * D;
15146+
APFloat BC = B * C;
15147+
ResR = AC - BD;
15148+
ResI = AD + BC;
15149+
if (ResR.isNaN() && ResI.isNaN()) {
15150+
bool Recalc = false;
15151+
if (A.isInfinity() || B.isInfinity()) {
15152+
A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
15153+
A);
15154+
B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
15155+
B);
15156+
if (C.isNaN())
15157+
C = APFloat::copySign(APFloat(C.getSemantics()), C);
15158+
if (D.isNaN())
15159+
D = APFloat::copySign(APFloat(D.getSemantics()), D);
15160+
Recalc = true;
15161+
}
15162+
if (C.isInfinity() || D.isInfinity()) {
15163+
C = APFloat::copySign(APFloat(C.getSemantics(), C.isInfinity() ? 1 : 0),
15164+
C);
15165+
D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
15166+
D);
15167+
if (A.isNaN())
15168+
A = APFloat::copySign(APFloat(A.getSemantics()), A);
15169+
if (B.isNaN())
15170+
B = APFloat::copySign(APFloat(B.getSemantics()), B);
15171+
Recalc = true;
15172+
}
15173+
if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
15174+
BC.isInfinity())) {
15175+
if (A.isNaN())
15176+
A = APFloat::copySign(APFloat(A.getSemantics()), A);
15177+
if (B.isNaN())
15178+
B = APFloat::copySign(APFloat(B.getSemantics()), B);
15179+
if (C.isNaN())
15180+
C = APFloat::copySign(APFloat(C.getSemantics()), C);
15181+
if (D.isNaN())
15182+
D = APFloat::copySign(APFloat(D.getSemantics()), D);
15183+
Recalc = true;
15184+
}
15185+
if (Recalc) {
15186+
ResR = APFloat::getInf(A.getSemantics()) * (A * C - B * D);
15187+
ResI = APFloat::getInf(A.getSemantics()) * (A * D + B * C);
15188+
}
15189+
}
15190+
}
15191+
1512915192
bool ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
1513015193
if (E->isPtrMemOp() || E->isAssignmentOp() || E->getOpcode() == BO_Comma)
1513115194
return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
@@ -15225,55 +15288,7 @@ bool ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
1522515288
!handleFloatFloatBinOp(Info, E, ResI, BO_Mul, B))
1522615289
return false;
1522715290
} else {
15228-
// In the fully general case, we need to handle NaNs and infinities
15229-
// robustly.
15230-
APFloat AC = A * C;
15231-
APFloat BD = B * D;
15232-
APFloat AD = A * D;
15233-
APFloat BC = B * C;
15234-
ResR = AC - BD;
15235-
ResI = AD + BC;
15236-
if (ResR.isNaN() && ResI.isNaN()) {
15237-
bool Recalc = false;
15238-
if (A.isInfinity() || B.isInfinity()) {
15239-
A = APFloat::copySign(
15240-
APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0), A);
15241-
B = APFloat::copySign(
15242-
APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0), B);
15243-
if (C.isNaN())
15244-
C = APFloat::copySign(APFloat(C.getSemantics()), C);
15245-
if (D.isNaN())
15246-
D = APFloat::copySign(APFloat(D.getSemantics()), D);
15247-
Recalc = true;
15248-
}
15249-
if (C.isInfinity() || D.isInfinity()) {
15250-
C = APFloat::copySign(
15251-
APFloat(C.getSemantics(), C.isInfinity() ? 1 : 0), C);
15252-
D = APFloat::copySign(
15253-
APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0), D);
15254-
if (A.isNaN())
15255-
A = APFloat::copySign(APFloat(A.getSemantics()), A);
15256-
if (B.isNaN())
15257-
B = APFloat::copySign(APFloat(B.getSemantics()), B);
15258-
Recalc = true;
15259-
}
15260-
if (!Recalc && (AC.isInfinity() || BD.isInfinity() ||
15261-
AD.isInfinity() || BC.isInfinity())) {
15262-
if (A.isNaN())
15263-
A = APFloat::copySign(APFloat(A.getSemantics()), A);
15264-
if (B.isNaN())
15265-
B = APFloat::copySign(APFloat(B.getSemantics()), B);
15266-
if (C.isNaN())
15267-
C = APFloat::copySign(APFloat(C.getSemantics()), C);
15268-
if (D.isNaN())
15269-
D = APFloat::copySign(APFloat(D.getSemantics()), D);
15270-
Recalc = true;
15271-
}
15272-
if (Recalc) {
15273-
ResR = APFloat::getInf(A.getSemantics()) * (A * C - B * D);
15274-
ResI = APFloat::getInf(A.getSemantics()) * (A * D + B * C);
15275-
}
15276-
}
15291+
HandleComplexComplexMul(A, B, C, D, ResR, ResI);
1527715292
}
1527815293
} else {
1527915294
ComplexValue LHS = Result;

clang/lib/AST/Interp/ByteCodeExprGen.cpp

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,22 @@ bool ByteCodeExprGen<Emitter>::VisitComplexBinOp(const BinaryOperator *E) {
876876
if (const auto *AT = RHSType->getAs<AtomicType>())
877877
RHSType = AT->getValueType();
878878

879+
// For ComplexComplex Mul, we have special ops to make their implementation
880+
// easier.
881+
BinaryOperatorKind Op = E->getOpcode();
882+
if (Op == BO_Mul && LHSType->isAnyComplexType() &&
883+
RHSType->isAnyComplexType()) {
884+
assert(classifyPrim(LHSType->getAs<ComplexType>()->getElementType()) ==
885+
classifyPrim(RHSType->getAs<ComplexType>()->getElementType()));
886+
PrimType ElemT =
887+
classifyPrim(LHSType->getAs<ComplexType>()->getElementType());
888+
if (!this->visit(LHS))
889+
return false;
890+
if (!this->visit(RHS))
891+
return false;
892+
return this->emitMulc(ElemT, E);
893+
}
894+
879895
// Evaluate LHS and save value to LHSOffset.
880896
bool LHSIsComplex;
881897
unsigned LHSOffset;
@@ -919,38 +935,37 @@ bool ByteCodeExprGen<Emitter>::VisitComplexBinOp(const BinaryOperator *E) {
919935
// For both LHS and RHS, either load the value from the complex pointer, or
920936
// directly from the local variable. For index 1 (i.e. the imaginary part),
921937
// just load 0 and do the operation anyway.
922-
auto loadComplexValue = [this](bool IsComplex, unsigned ElemIndex,
923-
unsigned Offset, const Expr *E) -> bool {
938+
auto loadComplexValue = [this](bool IsComplex, bool LoadZero,
939+
unsigned ElemIndex, unsigned Offset,
940+
const Expr *E) -> bool {
924941
if (IsComplex) {
925942
if (!this->emitGetLocal(PT_Ptr, Offset, E))
926943
return false;
927944
return this->emitArrayElemPop(classifyComplexElementType(E->getType()),
928945
ElemIndex, E);
929946
}
930-
if (ElemIndex == 0)
947+
if (ElemIndex == 0 || !LoadZero)
931948
return this->emitGetLocal(classifyPrim(E->getType()), Offset, E);
932949
return this->visitZeroInitializer(classifyPrim(E->getType()), E->getType(),
933950
E);
934951
};
935952

936953
// Now we can get pointers to the LHS and RHS from the offsets above.
937-
BinaryOperatorKind Op = E->getOpcode();
938954
for (unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
939955
// Result pointer for the store later.
940956
if (!this->DiscardResult) {
941957
if (!this->emitGetLocal(PT_Ptr, ResultOffset, E))
942958
return false;
943959
}
944960

945-
if (!loadComplexValue(LHSIsComplex, ElemIndex, LHSOffset, LHS))
946-
return false;
947-
948-
if (!loadComplexValue(RHSIsComplex, ElemIndex, RHSOffset, RHS))
949-
return false;
950-
951961
// The actual operation.
952962
switch (Op) {
953963
case BO_Add:
964+
if (!loadComplexValue(LHSIsComplex, true, ElemIndex, LHSOffset, LHS))
965+
return false;
966+
967+
if (!loadComplexValue(RHSIsComplex, true, ElemIndex, RHSOffset, RHS))
968+
return false;
954969
if (ResultElemT == PT_Float) {
955970
if (!this->emitAddf(getRoundingMode(E), E))
956971
return false;
@@ -960,6 +975,11 @@ bool ByteCodeExprGen<Emitter>::VisitComplexBinOp(const BinaryOperator *E) {
960975
}
961976
break;
962977
case BO_Sub:
978+
if (!loadComplexValue(LHSIsComplex, true, ElemIndex, LHSOffset, LHS))
979+
return false;
980+
981+
if (!loadComplexValue(RHSIsComplex, true, ElemIndex, RHSOffset, RHS))
982+
return false;
963983
if (ResultElemT == PT_Float) {
964984
if (!this->emitSubf(getRoundingMode(E), E))
965985
return false;
@@ -968,6 +988,21 @@ bool ByteCodeExprGen<Emitter>::VisitComplexBinOp(const BinaryOperator *E) {
968988
return false;
969989
}
970990
break;
991+
case BO_Mul:
992+
if (!loadComplexValue(LHSIsComplex, false, ElemIndex, LHSOffset, LHS))
993+
return false;
994+
995+
if (!loadComplexValue(RHSIsComplex, false, ElemIndex, RHSOffset, RHS))
996+
return false;
997+
998+
if (ResultElemT == PT_Float) {
999+
if (!this->emitMulf(getRoundingMode(E), E))
1000+
return false;
1001+
} else {
1002+
if (!this->emitMul(ResultElemT, E))
1003+
return false;
1004+
}
1005+
break;
9711006

9721007
default:
9731008
return false;

0 commit comments

Comments
 (0)