Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
33de6aa
[Clang][NFC] Fix a typo in FunctionDecl (#167677)
zyn0217 Nov 12, 2025
07cd105
[AArch64] Add 'REQUIRES: asserts' to regalloc-hint-movprfx.mir
sdesmalen-arm Nov 12, 2025
7838dbe
[Flang][OpenMP] Add Lowering support for Collapse with Taskloop (#166…
Stylie777 Nov 12, 2025
c5eb7eb
[OpenMP] Add more comments to `ConstructDecompositionT.h`, NFC (#167564)
kparzysz Nov 12, 2025
0f4dc93
[lldb][Language] Pass SymbolNameFitsToLanguage parameter by const-ref…
Michael137 Nov 12, 2025
f6cf44a
[lldb][ObjC][NFC] Rewrite IsPossibleObjCMethodName in terms of llvm::…
Michael137 Nov 12, 2025
448146d
[llvm-c] Add bindings for DbgRecord (#166383)
arthaud Nov 12, 2025
1f58cbe
[DAG] Fold (umin (sub a b) a) -> (usubo a b); (select usubo.1 a usubo…
ckoparkar Nov 12, 2025
aca28f1
[libc++] Optimize __tree copy/move constructor/assignment with alloca…
philnik777 Nov 12, 2025
09fd430
[lldb-dap] Refactor event thread (#166948)
da-viper Nov 12, 2025
1e4b9e4
[flang][NFC] Strip trailing whitespace from tests (3 of N)
tarunprabhu Nov 12, 2025
62d1a08
[LV] Use ExtractLane(LastActiveLane, V) live outs when tail-folding. …
fhahn Nov 12, 2025
b6dd511
[X86] AVX512 optimised CTLZ/CTTZ implementations for i256/i512 scalar…
RKSimon Nov 12, 2025
1deaedd
[ADT] Make DenseMapBase::swap the public entry point (#167650)
kazutakahirata Nov 12, 2025
834a3cc
[SPIRV] Handle ptrcast between array and vector types (#166418)
s-perron Nov 12, 2025
5932477
[libc] Add support for MVE to Arm startup code (#167338)
vhscampos Nov 12, 2025
8280070
[VectorCombine] Try to scalarize vector loads feeding bitcast instruc…
juliannagele Nov 12, 2025
d4b43f0
[MLIR][NFC] Fix minor spelling issues (#167606)
ashermancinelli Nov 12, 2025
0df5dee
[OpenMP] Apply COLLAPSE to innermost leaf that allows it (#167565)
kparzysz Nov 12, 2025
7647fc8
[LifetimeSafety] Add support for conditional operators (#167240)
usx95 Nov 12, 2025
f240a73
[CIR] Upstream Load/Store Complex with volatile qualifier (#167216)
AmrDeveloper Nov 12, 2025
ec085e5
[mlir][tosa] Add missing ext-mxfp description (#167665)
lhutton1 Nov 12, 2025
4d1f249
[ARM] Use TargetMachine over Subtarget in ARMAsmPrinter (#166329)
davemgreen Nov 12, 2025
7d5c11f
[Windows] Adjust exported symbols in static builds with plugin suppor…
vmustya Nov 12, 2025
0845c5a
[Mips] Remove implicit conversions of MCRegister to unsigned. NFC (#1…
topperc Nov 12, 2025
d4847f7
[X86] Remove implicit conversions of MCRegister to unsigned. NFC (#16…
topperc Nov 12, 2025
33a352f
[Flang][OpenMP] - Fix the mapping flags used on descriptors mapped by…
bhandarkar-pranav Nov 12, 2025
5b56816
[NFC][SPIRV][IRTranslator] Replace leftover `MF->getTarget().getTarge…
jmmartinez Nov 12, 2025
3f7ac6e
[RISCV] Update SpacemiT-X60 vector permutation instructions latencies…
mikhailramalho Nov 12, 2025
0bbf644
Remove unused standard headers: memory, unordered_* (#167297)
serge-sans-paille Nov 12, 2025
ca72e8d
[RISCV] Expand multiplication by `2^N * 3/5/9 + 1` with SHL_ADD (#166…
pfusik Nov 12, 2025
a3058d5
[libc++] Guard fileno() and isatty() usage correctly for Newlib. (#16…
wecing Nov 12, 2025
c0ac0c4
[PowerPC] Add intrinsic support for xvrlw (#167349)
lei137 Nov 12, 2025
19043b2
[OpenMP] Report errors when construct decomposition fails (#167568)
kparzysz Nov 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/include/clang/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -2335,7 +2335,7 @@ class FunctionDecl : public DeclaratorDecl,
}

void setDefaultedOrDeletedInfo(DefaultedOrDeletedFunctionInfo *Info);
DefaultedOrDeletedFunctionInfo *getDefalutedOrDeletedInfo() const;
DefaultedOrDeletedFunctionInfo *getDefaultedOrDeletedInfo() const;

/// Whether this function is variadic.
bool isVariadic() const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class FactsGenerator : public ConstStmtVisitor<FactsGenerator> {
void VisitUnaryOperator(const UnaryOperator *UO);
void VisitReturnStmt(const ReturnStmt *RS);
void VisitBinaryOperator(const BinaryOperator *BO);
void VisitConditionalOperator(const ConditionalOperator *CO);
void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *OCE);
void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *FCE);
void VisitInitListExpr(const InitListExpr *ILE);
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3180,7 +3180,7 @@ void FunctionDecl::DefaultedOrDeletedFunctionInfo::setDeletedMessage(
}

FunctionDecl::DefaultedOrDeletedFunctionInfo *
FunctionDecl::getDefalutedOrDeletedInfo() const {
FunctionDecl::getDefaultedOrDeletedInfo() const {
return FunctionDeclBits.HasDefaultedOrDeletedInfo ? DefaultedOrDeletedInfo
: nullptr;
}
Expand Down
9 changes: 9 additions & 0 deletions clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,15 @@ void FactsGenerator::VisitBinaryOperator(const BinaryOperator *BO) {
handleAssignment(BO->getLHS(), BO->getRHS());
}

void FactsGenerator::VisitConditionalOperator(const ConditionalOperator *CO) {
if (hasOrigin(CO)) {
// Merge origins from both branches of the conditional operator.
// We kill to clear the initial state and merge both origins into it.
killAndFlowOrigin(*CO, *CO->getTrueExpr());
flowOrigin(*CO, *CO->getFalseExpr());
}
}

void FactsGenerator::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *OCE) {
// Assignment operators have special "kill-then-propagate" semantics
// and are handled separately.
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ mlir::Value ComplexExprEmitter::emitLoadOfLValue(LValue lv,
cgf.cgm.errorNYI(loc, "emitLoadOfLValue with Atomic LV");

const Address srcAddr = lv.getAddress();
return builder.createLoad(cgf.getLoc(loc), srcAddr);
return builder.createLoad(cgf.getLoc(loc), srcAddr, lv.isVolatileQualified());
}

/// EmitStoreOfComplex - Store the specified real/imag parts into the
Expand All @@ -353,7 +353,7 @@ void ComplexExprEmitter::emitStoreOfComplex(mlir::Location loc, mlir::Value val,
}

const Address destAddr = lv.getAddress();
builder.createStore(loc, val, destAddr);
builder.createStore(loc, val, destAddr, lv.isVolatileQualified());
}

//===----------------------------------------------------------------------===//
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Sema/SemaDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8035,7 +8035,7 @@ class DefaultedComparisonVisitor {
DefaultedComparisonVisitor(Sema &S, CXXRecordDecl *RD, FunctionDecl *FD,
DefaultedComparisonKind DCK)
: S(S), RD(RD), FD(FD), DCK(DCK) {
if (auto *Info = FD->getDefalutedOrDeletedInfo()) {
if (auto *Info = FD->getDefaultedOrDeletedInfo()) {
// FIXME: Change CreateOverloadedBinOp to take an ArrayRef instead of an
// UnresolvedSet to avoid this copy.
Fns.assign(Info->getUnqualifiedLookups().begin(),
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5465,7 +5465,7 @@ TemplateDeclInstantiator::InitMethodInstantiation(CXXMethodDecl *New,
bool TemplateDeclInstantiator::SubstDefaultedFunction(FunctionDecl *New,
FunctionDecl *Tmpl) {
// Transfer across any unqualified lookups.
if (auto *DFI = Tmpl->getDefalutedOrDeletedInfo()) {
if (auto *DFI = Tmpl->getDefaultedOrDeletedInfo()) {
SmallVector<DeclAccessPair, 32> Lookups;
Lookups.reserve(DFI->getUnqualifiedLookups().size());
bool AnyChanged = false;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Serialization/ASTWriterDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -903,7 +903,7 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
Record.push_back(D->getODRHash());

if (D->isDefaulted() || D->isDeletedAsWritten()) {
if (auto *FDI = D->getDefalutedOrDeletedInfo()) {
if (auto *FDI = D->getDefaultedOrDeletedInfo()) {
// Store both that there is an DefaultedOrDeletedInfo and whether it
// contains a DeletedMessage.
StringLiteral *DeletedMessage = FDI->getDeletedMessage();
Expand Down
16 changes: 8 additions & 8 deletions clang/test/CIR/CodeGen/complex-compound-assignment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,18 +237,18 @@ void foo4() {
// CXX_CIR: %[[A_ADDR:.*]] = cir.alloca !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>, ["a"]
// CXX_CIR: %[[B_ADDR:.*]] = cir.alloca !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>, ["b"]
// CXX_CIR: %[[C_ADDR:.*]] = cir.alloca !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>, ["c", init]
// CXX_CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
// CXX_CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
// CXX_CIR: %[[TMP_A:.*]] = cir.load volatile {{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
// CXX_CIR: %[[TMP_B:.*]] = cir.load volatile {{.*}} %[[B_ADDR]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
// CXX_CIR: %[[RESULT:.*]] = cir.complex.add %[[TMP_B]], %[[TMP_A]] : !cir.complex<!s32i>
// CXX_CIR: cir.store{{.*}} %[[RESULT]], %[[B_ADDR]] : !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>
// CXX_CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
// CXX_CIR: cir.store volatile {{.*}} %[[RESULT]], %[[B_ADDR]] : !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>
// CXX_CIR: %[[TMP_B:.*]] = cir.load volatile {{.*}} %[[B_ADDR]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
// CXX_CIR: cir.store{{.*}} %[[TMP_B]], %[[C_ADDR]] : !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>

// CXX_LLVM: %[[A_ADDR:.*]] = alloca { i32, i32 }, i64 1, align 4
// CXX_LLVM: %[[B_ADDR:.*]] = alloca { i32, i32 }, i64 1, align 4
// CXX_LLVM: %[[C_ADDR:.*]] = alloca { i32, i32 }, i64 1, align 4
// CXX_LLVM: %[[TMP_A:.*]] = load { i32, i32 }, ptr %[[A_ADDR]], align 4
// CXX_LLVM: %[[TMP_B:.*]] = load { i32, i32 }, ptr %[[B_ADDR]], align 4
// CXX_LLVM: %[[TMP_A:.*]] = load volatile { i32, i32 }, ptr %[[A_ADDR]], align 4
// CXX_LLVM: %[[TMP_B:.*]] = load volatile { i32, i32 }, ptr %[[B_ADDR]], align 4
// CXX_LLVM: %[[B_REAL:.*]] = extractvalue { i32, i32 } %[[TMP_B]], 0
// CXX_LLVM: %[[B_IMAG:.*]] = extractvalue { i32, i32 } %[[TMP_B]], 1
// CXX_LLVM: %[[A_REAL:.*]] = extractvalue { i32, i32 } %[[TMP_A]], 0
Expand All @@ -257,8 +257,8 @@ void foo4() {
// CXX_LLVM: %[[ADD_IMAG:.*]] = add i32 %[[B_IMAG]], %[[A_IMAG]]
// CXX_LLVM: %[[TMP_RESULT:.*]] = insertvalue { i32, i32 } poison, i32 %[[ADD_REAL]], 0
// CXX_LLVM: %[[RESULT:.*]] = insertvalue { i32, i32 } %[[TMP_RESULT]], i32 %[[ADD_IMAG]], 1
// CXX_LLVM: store { i32, i32 } %[[RESULT]], ptr %[[B_ADDR]], align 4
// CXX_LLVM: %[[TMP_B:.*]] = load { i32, i32 }, ptr %[[B_ADDR]], align 4
// CXX_LLVM: store volatile { i32, i32 } %[[RESULT]], ptr %[[B_ADDR]], align 4
// CXX_LLVM: %[[TMP_B:.*]] = load volatile { i32, i32 }, ptr %[[B_ADDR]], align 4
// CXX_LLVM: store { i32, i32 } %[[TMP_B]], ptr %[[C_ADDR]], align 4

// CXX_OGCG: %[[A_ADDR:.*]] = alloca { i32, i32 }, align 4
Expand Down
143 changes: 143 additions & 0 deletions clang/test/CIR/CodeGen/complex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1534,3 +1534,146 @@ void imag_literal_gnu_extension() {
// OGCG: %[[C_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[C_ADDR]], i32 0, i32 1
// OGCG: store i32 0, ptr %[[C_REAL_PTR]], align 4
// OGCG: store i32 3, ptr %[[C_IMAG_PTR]], align 4

void load_store_volatile() {
volatile double _Complex a;
volatile double _Complex b;
a = b;

volatile int _Complex c;
volatile int _Complex d;
c = d;
}

// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.complex<!cir.double>, !cir.ptr<!cir.complex<!cir.double>>, ["a"]
// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.complex<!cir.double>, !cir.ptr<!cir.complex<!cir.double>>, ["b"]
// CIR: %[[C_ADDR:.*]] = cir.alloca !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>, ["c"]
// CIR: %[[D_ADDR:.*]] = cir.alloca !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>, ["d"]
// CIR: %[[TMP_B:.*]] = cir.load volatile {{.*}} %[[B_ADDR]] : !cir.ptr<!cir.complex<!cir.double>>, !cir.complex<!cir.double>
// CIR: cir.store volatile {{.*}} %[[TMP_B]], %[[A_ADDR]] : !cir.complex<!cir.double>, !cir.ptr<!cir.complex<!cir.double>>
// CIR: %[[TMP_D:.*]] = cir.load volatile {{.*}} %[[D_ADDR]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
// CIR: cir.store volatile {{.*}} %[[TMP_D]], %[[C_ADDR]] : !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>

// LLVM: %[[A_ADDR:.*]] = alloca { double, double }, i64 1, align 8
// LLVM: %[[B_ADDR:.*]] = alloca { double, double }, i64 1, align 8
// LLVM: %[[C_ADDR:.*]] = alloca { i32, i32 }, i64 1, align 4
// LLVM: %[[D_ADDR:.*]] = alloca { i32, i32 }, i64 1, align 4
// LLVM: %[[TMP_B:.*]] = load volatile { double, double }, ptr %[[B_ADDR]], align 8
// LLVM: store volatile { double, double } %[[TMP_B]], ptr %[[A_ADDR]], align 8
// LLVM: %[[TMP_D:.*]] = load volatile { i32, i32 }, ptr %[[D_ADDR]], align 4
// LLVM: store volatile { i32, i32 } %[[TMP_D]], ptr %[[C_ADDR]], align 4

// OGCG: %[[A_ADDR:.*]] = alloca { double, double }, align 8
// OGCG: %[[B_ADDR:.*]] = alloca { double, double }, align 8
// OGCG: %[[C_ADDR:.*]] = alloca { i32, i32 }, align 4
// OGCG: %[[D_ADDR:.*]] = alloca { i32, i32 }, align 4
// OGCG: %[[B_REAL_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[B_ADDR]], i32 0, i32 0
// OGCG: %[[B_REAL:.*]] = load volatile double, ptr %[[B_REAL_PTR]], align 8
// OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[B_ADDR]], i32 0, i32 1
// OGCG: %[[B_IMAG:.*]] = load volatile double, ptr %[[B_IMAG_PTR]], align 8
// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[A_ADDR]], i32 0, i32 0
// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[A_ADDR]], i32 0, i32 1
// OGCG: store volatile double %[[B_REAL]], ptr %[[A_REAL_PTR]], align 8
// OGCG: store volatile double %[[B_IMAG]], ptr %[[A_IMAG_PTR]], align 8
// OGCG: %[[D_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[D_ADDR]], i32 0, i32 0
// OGCG: %[[D_REAL:.*]] = load volatile i32, ptr %[[D_REAL_PTR]], align 4
// OGCG: %[[D_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[D_ADDR]], i32 0, i32 1
// OGCG: %[[D_IMAG:.*]] = load volatile i32, ptr %[[D_IMAG_PTR]], align 4
// OGCG: %[[C_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[C_ADDR]], i32 0, i32 0
// OGCG: %[[C_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[C_ADDR]], i32 0, i32 1
// OGCG: store volatile i32 %[[D_REAL]], ptr %[[C_REAL_PTR]], align 4
// OGCG: store volatile i32 %[[D_IMAG]], ptr %[[C_IMAG_PTR]], align 4


void load_store_volatile_2() {
volatile double _Complex av;
double _Complex a;
av = a;

double _Complex b;
volatile double _Complex bv;
b = bv;

int _Complex c;
volatile int _Complex cv;
c = cv;

volatile int _Complex dv;
int _Complex d;
dv = d;
}

// CIR: %[[AV_ADDR:.*]] = cir.alloca !cir.complex<!cir.double>, !cir.ptr<!cir.complex<!cir.double>>, ["av"]
// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.complex<!cir.double>, !cir.ptr<!cir.complex<!cir.double>>, ["a"]
// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.complex<!cir.double>, !cir.ptr<!cir.complex<!cir.double>>, ["b"]
// CIR: %[[BV_ADDR:.*]] = cir.alloca !cir.complex<!cir.double>, !cir.ptr<!cir.complex<!cir.double>>, ["bv"]
// CIR: %[[C_ADDR:.*]] = cir.alloca !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>, ["c"]
// CIR: %[[CV_ADDR:.*]] = cir.alloca !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>, ["cv"]
// CIR: %[[DV_ADDR:.*]] = cir.alloca !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>, ["dv"]
// CIR: %[[D_ADDR:.*]] = cir.alloca !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>, ["d"]
// CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!cir.double>>, !cir.complex<!cir.double>
// CIR: cir.store volatile {{.*}} %[[TMP_A]], %[[AV_ADDR]] : !cir.complex<!cir.double>, !cir.ptr<!cir.complex<!cir.double>>
// CIR: %[[TMP_BV:.*]] = cir.load volatile {{.*}} %[[BV_ADDR]] : !cir.ptr<!cir.complex<!cir.double>>, !cir.complex<!cir.double>
// CIR: cir.store {{.*}} %[[TMP_BV]], %[[B_ADDR]] : !cir.complex<!cir.double>, !cir.ptr<!cir.complex<!cir.double>>
// CIR: %[[TMP_CV:.*]] = cir.load volatile {{.*}} %[[CV_ADDR]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
// CIR: cir.store {{.*}} %[[TMP_CV]], %[[C_ADDR]] : !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>
// CIR: %[[TMP_D:.*]] = cir.load {{.*}} %[[D_ADDR]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
// CIR: cir.store volatile {{.*}} %[[TMP_D]], %[[DV_ADDR]] : !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>

// LLVM: %[[AV_ADDR:.*]] = alloca { double, double }, i64 1, align 8
// LLVM: %[[A_ADDR:.*]] = alloca { double, double }, i64 1, align 8
// LLVM: %[[B_ADDR:.*]] = alloca { double, double }, i64 1, align 8
// LLVM: %[[BV_ADDR:.*]] = alloca { double, double }, i64 1, align 8
// LLVM: %[[C_ADDR:.*]] = alloca { i32, i32 }, i64 1, align 4
// LLVM: %[[CV_ADDR:.*]] = alloca { i32, i32 }, i64 1, align 4
// LLVM: %[[DV_ADDR:.*]] = alloca { i32, i32 }, i64 1, align 4
// LLVM: %[[D_ADDR:.*]] = alloca { i32, i32 }, i64 1, align 4
// LLVM: %[[TMP_A:.*]] = load { double, double }, ptr %[[A_ADDR]], align 8
// LLVM: store volatile { double, double } %[[TMP_A]], ptr %[[AV_ADDR]], align 8
// LLVM: %[[TMP_BV:.*]] = load volatile { double, double }, ptr %[[BV_ADDR]], align 8
// LLVM: store { double, double } %[[TMP_BV]], ptr %[[B_ADDR]], align 8
// LLVM: %[[TMP_CV:.*]] = load volatile { i32, i32 }, ptr %[[CV_ADDR]], align 4
// LLVM: store { i32, i32 } %[[TMP_CV]], ptr %[[C_ADDR]], align 4
// LLVM: %[[TMP_D:.*]] = load { i32, i32 }, ptr %[[D_ADDR]], align 4
// LLVM: store volatile { i32, i32 } %[[TMP_D]], ptr %[[DV_ADDR]], align 4

// OGCG: %[[AV_ADDR:.*]] = alloca { double, double }, align 8
// OGCG: %[[A_ADDR:.*]] = alloca { double, double }, align 8
// OGCG: %[[B_ADDR:.*]] = alloca { double, double }, align 8
// OGCG: %[[BV_ADDR:.*]] = alloca { double, double }, align 8
// OGCG: %[[C_ADDR:.*]] = alloca { i32, i32 }, align 4
// OGCG: %[[CV_ADDR:.*]] = alloca { i32, i32 }, align 4
// OGCG: %[[DV_ADDR:.*]] = alloca { i32, i32 }, align 4
// OGCG: %[[D_ADDR:.*]] = alloca { i32, i32 }, align 4
// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[A_ADDR]], i32 0, i32 0
// OGCG: %[[A_REAL:.*]] = load double, ptr %[[A_REAL_PTR]], align 8
// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[A_ADDR]], i32 0, i32 1
// OGCG: %[[A_IMAG:.*]] = load double, ptr %[[A_IMAG_PTR]], align 8
// OGCG: %[[AV_REAL_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[AV_ADDR]], i32 0, i32 0
// OGCG: %[[AV_IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[AV_ADDR]], i32 0, i32 1
// OGCG: store volatile double %[[A_REAL]], ptr %[[AV_REAL_PTR]], align 8
// OGCG: store volatile double %[[A_IMAG]], ptr %[[AV_IMAG_PTR]], align 8
// OGCG: %[[BV_REAL_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[BV_ADDR]], i32 0, i32 0
// OGCG: %[[BV_REAL:.*]] = load volatile double, ptr %[[BV_REAL_PTR]], align 8
// OGCG: %[[BV_IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[BV_ADDR]], i32 0, i32 1
// OGCG: %[[BV_IMAG:.*]] = load volatile double, ptr %[[BV_IMAG_PTR]], align 8
// OGCG: %[[B_REAL_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[B_ADDR]], i32 0, i32 0
// OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[B_ADDR]], i32 0, i32 1
// OGCG: store double %[[BV_REAL]], ptr %[[B_REAL_PTR]], align 8
// OGCG: store double %[[BV_IMAG]], ptr %[[B_IMAG_PTR]], align 8
// OGCG: %[[CV_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[CV_ADDR]], i32 0, i32 0
// OGCG: %[[CV_REAL:.*]] = load volatile i32, ptr %[[CV_REAL_PTR]], align 4
// OGCG: %[[CV_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[CV_ADDR]], i32 0, i32 1
// OGCG: %[[CV_IMAG:.*]] = load volatile i32, ptr %[[CV_IMAG_PTR]], align 4
// OGCG: %[[C_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[C_ADDR]], i32 0, i32 0
// OGCG: %[[C_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[C_ADDR]], i32 0, i32 1
// OGCG: store i32 %[[CV_REAL]], ptr %[[C_REAL_PTR]], align 4
// OGCG: store i32 %[[CV_IMAG]], ptr %[[C_IMAG_PTR]], align 4
// OGCG: %[[D_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[D_ADDR]], i32 0, i32 0
// OGCG: %[[D_REAL:.*]] = load i32, ptr %[[D_REAL_PTR]], align 4
// OGCG: %[[D_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[D_ADDR]], i32 0, i32 1
// OGCG: %[[D_IMAG:.*]] = load i32, ptr %[[D_IMAG_PTR]], align 4
// OGCG: %[[DV_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[DV_ADDR]], i32 0, i32 0
// OGCG: %[[DV_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[DV_ADDR]], i32 0, i32 1
// OGCG: store volatile i32 %[[D_REAL]], ptr %[[DV_REAL_PTR]], align 4
// OGCG: store volatile i32 %[[D_IMAG]], ptr %[[DV_IMAG_PTR]], align 4
17 changes: 17 additions & 0 deletions clang/test/Sema/warn-lifetime-safety-dataflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -414,3 +414,20 @@ void test_use_lifetimebound_call() {
// CHECK: Expire ([[L_Y]] (Path: y))
// CHECK: Expire ([[L_X]] (Path: x))
}
// CHECK-LABEL: Function: test_conditional_operator
void test_conditional_operator(bool cond) {
MyObj x, y;
MyObj *p = cond ? &x : &y;
// CHECK: Block B{{[0-9]+}}:
// CHECK: Issue ([[L_X:[0-9]+]] (Path: x), ToOrigin: [[O_DRE_X:[0-9]+]] (Expr: DeclRefExpr))
// CHECK: OriginFlow (Dest: [[O_ADDR_X:[0-9]+]] (Expr: UnaryOperator), Src: [[O_DRE_X]] (Expr: DeclRefExpr))
// CHECK: Block B{{[0-9]+}}:
// CHECK: Issue ([[L_Y:[0-9]+]] (Path: y), ToOrigin: [[O_DRE_Y:[0-9]+]] (Expr: DeclRefExpr))
// CHECK: OriginFlow (Dest: [[O_ADDR_Y:[0-9]+]] (Expr: UnaryOperator), Src: [[O_DRE_Y]] (Expr: DeclRefExpr))
// CHECK: Block B{{[0-9]+}}:
// CHECK: OriginFlow (Dest: [[O_COND_OP:[0-9]+]] (Expr: ConditionalOperator), Src: [[O_ADDR_X]] (Expr: UnaryOperator))
// CHECK: OriginFlow (Dest: [[O_COND_OP]] (Expr: ConditionalOperator), Src: [[O_ADDR_Y]] (Expr: UnaryOperator), Merge)
// CHECK: OriginFlow (Dest: [[O_P:[0-9]+]] (Decl: p), Src: [[O_COND_OP]] (Expr: ConditionalOperator))
// CHECK: Expire ([[L_Y]] (Path: y))
// CHECK: Expire ([[L_X]] (Path: x))
}
Loading
Loading