Skip to content

Commit 6434034

Browse files
SC llvm teamSC llvm team
authored andcommitted
Merged main:7429950d840b8fec3d9a48d00e612a3240c2be83 into amd-gfx:49c66abb8fcb
Local branch amd-gfx 49c66ab Merged main:b590ba73a76609bace9949ea8195d2ee8213cb3f into amd-gfx:300e9c581b42 Remote branch main 7429950 [clang][CodeComplete] Recurse into the subexpression of deref operator in getApproximateType (llvm#93404)
2 parents 49c66ab + 7429950 commit 6434034

File tree

24 files changed

+251
-504
lines changed

24 files changed

+251
-504
lines changed

clang/docs/analyzer/checkers.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2858,6 +2858,16 @@ The check corresponds to CERT rule
28582858
return putenv(env); // putenv function should not be called with stack-allocated string
28592859
}
28602860
2861+
There is one case where the checker can report a false positive. This is when
2862+
the stack-allocated array is used at `putenv` in a function or code branch that
2863+
does not return (calls `fork` or `exec` like function).
2864+
2865+
Another special case is if the `putenv` is called from function `main`. Here
2866+
the stack is deallocated at the end of the program and it should be no problem
2867+
to use the stack-allocated string (a multi-threaded program may require more
2868+
attention). The checker does not warn for cases when stack space of `main` is
2869+
used at the `putenv` call.
2870+
28612871
.. _alpha-security-ReturnPtrRange:
28622872
28632873
alpha.security.ReturnPtrRange (C)

clang/lib/Sema/SemaCodeComplete.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5692,8 +5692,15 @@ QualType getApproximateType(const Expr *E) {
56925692
}
56935693
}
56945694
if (const auto *UO = llvm::dyn_cast<UnaryOperator>(E)) {
5695-
if (UO->getOpcode() == UnaryOperatorKind::UO_Deref)
5696-
return UO->getSubExpr()->getType()->getPointeeType();
5695+
if (UO->getOpcode() == UnaryOperatorKind::UO_Deref) {
5696+
// We recurse into the subexpression because it could be of dependent
5697+
// type.
5698+
if (auto Pointee = getApproximateType(UO->getSubExpr())->getPointeeType();
5699+
!Pointee.isNull())
5700+
return Pointee;
5701+
// Our caller expects a non-null result, even though the SubType is
5702+
// supposed to have a pointee. Fall through to Unresolved anyway.
5703+
}
56975704
}
56985705
return Unresolved;
56995706
}

clang/lib/StaticAnalyzer/Checkers/PutenvStackArrayChecker.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,14 @@ void PutenvStackArrayChecker::checkPostCall(const CallEvent &Call,
4444

4545
SVal ArgV = Call.getArgSVal(0);
4646
const Expr *ArgExpr = Call.getArgExpr(0);
47-
const MemSpaceRegion *MSR = ArgV.getAsRegion()->getMemorySpace();
4847

49-
if (!isa<StackSpaceRegion>(MSR))
48+
const auto *SSR =
49+
dyn_cast<StackSpaceRegion>(ArgV.getAsRegion()->getMemorySpace());
50+
if (!SSR)
51+
return;
52+
const auto *StackFrameFuncD =
53+
dyn_cast_or_null<FunctionDecl>(SSR->getStackFrame()->getDecl());
54+
if (StackFrameFuncD && StackFrameFuncD->isMain())
5055
return;
5156

5257
StringRef ErrorMsg = "The 'putenv' function should not be called with "

clang/test/Analysis/putenv-stack-array.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@ int test_auto_var_subarray() {
4545
return putenv(env + 100); // expected-warning{{The 'putenv' function should not be called with}}
4646
}
4747

48+
int f_test_auto_var_call(char *env) {
49+
return putenv(env); // expected-warning{{The 'putenv' function should not be called with}}
50+
}
51+
52+
int test_auto_var_call() {
53+
char env[1024];
54+
return f_test_auto_var_call(env);
55+
}
56+
4857
int test_constant() {
4958
char *env = "TEST";
5059
return putenv(env); // no-warning: data is not on the stack
@@ -68,3 +77,14 @@ void test_auto_var_reset() {
6877
// become invalid.
6978
putenv((char *)"NAME=anothervalue");
7079
}
80+
81+
void f_main(char *env) {
82+
putenv(env); // no warning: string allocated in stack of 'main'
83+
}
84+
85+
int main(int argc, char **argv) {
86+
char env[] = "NAME=value";
87+
putenv(env); // no warning: string allocated in stack of 'main'
88+
f_main(env);
89+
return 0;
90+
}

clang/test/CodeCompletion/member-access.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,4 +367,20 @@ class A {
367367
// CHECK-DEREF-THIS: [#void#]function()
368368
}
369369
};
370+
371+
template <typename Element>
372+
struct RepeatedField {
373+
void Add();
374+
};
375+
376+
template <typename T>
377+
RepeatedField<T>* MutableRepeatedField() {}
378+
379+
template <class T>
380+
void Foo() {
381+
auto& C = *MutableRepeatedField<T>();
382+
C.
383+
}
384+
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:382:5 %s -o - | FileCheck -check-prefix=CHECK-DEREF-DEPENDENT %s
385+
// CHECK-DEREF-DEPENDENT: [#void#]Add()
370386
}

clang/test/SemaTemplate/deduction-guide.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,3 +299,34 @@ using AFoo = Foo<G<U>>;
299299
// CHECK-NEXT: `-ParmVarDecl {{.*}} 'G<int>'
300300

301301
AFoo aa(G<int>{});
302+
303+
namespace TTP {
304+
template<typename> struct A {};
305+
306+
template<class T> struct B {
307+
template<template <class> typename TT> B(TT<T>);
308+
};
309+
310+
B b(A<int>{});
311+
} // namespace TTP
312+
313+
// CHECK-LABEL: Dumping TTP::<deduction guide for B>:
314+
// CHECK-NEXT: FunctionTemplateDecl 0x{{.+}} <{{.+}}:[[# @LINE - 7]]:5, col:51>
315+
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} class depth 0 index 0 T{{$}}
316+
// CHECK-NEXT: |-TemplateTemplateParmDecl {{.+}} depth 0 index 1 TT{{$}}
317+
// CHECK-NEXT: | `-TemplateTypeParmDecl {{.+}} class depth 1 index 0{{$}}
318+
// CHECK-NEXT: |-CXXDeductionGuideDecl {{.+}} 'auto (<T>) -> B<T>'{{$}}
319+
// CHECK-NEXT: | `-ParmVarDecl {{.+}} '<T>'{{$}}
320+
// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} 'auto (A<int>) -> TTP::B<int>'
321+
// CHECK-NEXT: |-TemplateArgument type 'int'
322+
// CHECK-NEXT: | `-BuiltinType {{.+}} 'int'{{$}}
323+
// CHECK-NEXT: |-TemplateArgument template A
324+
// CHECK-NEXT: `-ParmVarDecl {{.+}} 'A<int>':'TTP::A<int>'{{$}}
325+
// CHECK-NEXT: FunctionProtoType {{.+}} 'auto (<T>) -> B<T>' dependent trailing_return cdecl{{$}}
326+
// CHECK-NEXT: |-InjectedClassNameType {{.+}} 'B<T>' dependent{{$}}
327+
// CHECK-NEXT: | `-CXXRecord {{.+}} 'B'{{$}}
328+
// CHECK-NEXT: `-ElaboratedType {{.+}} '<T>' sugar dependent{{$}}
329+
// CHECK-NEXT: `-TemplateSpecializationType {{.+}} '<T>' dependent {{$}}
330+
// CHECK-NEXT: `-TemplateArgument type 'T'{{$}}
331+
// CHECK-NEXT: `-TemplateTypeParmType {{.+}} 'T' dependent depth 0 index 0{{$}}
332+
// CHECK-NEXT: `-TemplateTypeParm {{.+}} 'T'{{$}}

clang/unittests/StaticAnalyzer/MemRegionDescriptiveNameTest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ void reportDescriptiveName(int *p);
9090
extern int* ptr;
9191
extern int array[3];
9292
void top() {
93-
reportDescriptiveName(&array[(long)ptr]);
93+
reportDescriptiveName(&array[(long long)ptr]);
9494
})cpp";
9595

9696
std::string Output;

lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -678,8 +678,8 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process,
678678
loaded_image->Clear();
679679

680680
std::string path;
681-
path = remote_file.GetPath();
682-
681+
path = remote_file.GetPath(false);
682+
683683
ThreadSP thread_sp = process->GetThreadList().GetExpressionExecutionThread();
684684
if (!thread_sp) {
685685
error.SetErrorString("dlopen error: no thread available to call dlopen.");

llvm/include/llvm/Config/llvm-config.h.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
/* Indicate that this is LLVM compiled from the amd-gfx branch. */
1818
#define LLVM_HAVE_BRANCH_AMD_GFX
19-
#define LLVM_MAIN_REVISION 499830
19+
#define LLVM_MAIN_REVISION 499845
2020

2121
/* Define if LLVM_ENABLE_DUMP is enabled */
2222
#cmakedefine LLVM_ENABLE_DUMP

llvm/include/llvm/Support/Discriminator.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,12 @@ static inline unsigned getBaseFSBitEnd() {
121121
}
122122

123123
// Set bits in range of [0 .. n] to 1. Used in FS Discriminators.
124-
static inline unsigned getN1Bits(unsigned N) {
124+
static inline unsigned getN1Bits(int N) {
125+
// Work around the g++ bug that folding "(1U << (N + 1)) - 1" to 0.
126+
if (N == 31)
127+
return 0xFFFFFFFF;
125128
assert((N < 32) && "N is invalid");
126-
return 0xFFFFFFFF >> (31 - N);
129+
return (1U << (N + 1)) - 1;
127130
}
128131

129132
} // namespace llvm

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,6 @@
197197
#include "llvm/ADT/SmallVector.h"
198198
#include "llvm/ADT/Statistic.h"
199199
#include "llvm/CodeGen/LivePhysRegs.h"
200-
#include "llvm/CodeGen/LiveRegUnits.h"
201200
#include "llvm/CodeGen/MachineBasicBlock.h"
202201
#include "llvm/CodeGen/MachineFrameInfo.h"
203202
#include "llvm/CodeGen/MachineFunction.h"
@@ -989,7 +988,7 @@ void AArch64FrameLowering::emitZeroCallUsedRegs(BitVector RegsToZero,
989988
}
990989
}
991990

992-
static void getLiveRegsForEntryMBB(LiveRegUnits &LiveRegs,
991+
static void getLiveRegsForEntryMBB(LivePhysRegs &LiveRegs,
993992
const MachineBasicBlock &MBB) {
994993
const MachineFunction *MF = MBB.getParent();
995994
LiveRegs.addLiveIns(MBB);
@@ -1019,18 +1018,16 @@ static Register findScratchNonCalleeSaveRegister(MachineBasicBlock *MBB) {
10191018

10201019
const AArch64Subtarget &Subtarget = MF->getSubtarget<AArch64Subtarget>();
10211020
const AArch64RegisterInfo &TRI = *Subtarget.getRegisterInfo();
1022-
LiveRegUnits LiveRegs(TRI);
1021+
LivePhysRegs LiveRegs(TRI);
10231022
getLiveRegsForEntryMBB(LiveRegs, *MBB);
10241023

10251024
// Prefer X9 since it was historically used for the prologue scratch reg.
1026-
if (LiveRegs.available(AArch64::X9))
1025+
const MachineRegisterInfo &MRI = MF->getRegInfo();
1026+
if (LiveRegs.available(MRI, AArch64::X9))
10271027
return AArch64::X9;
10281028

1029-
BitVector Allocatable =
1030-
TRI.getAllocatableSet(*MF, TRI.getRegClass(AArch64::GPR64RegClassID));
1031-
1032-
for (unsigned Reg : Allocatable.set_bits()) {
1033-
if (LiveRegs.available(Reg))
1029+
for (unsigned Reg : AArch64::GPR64RegClass) {
1030+
if (LiveRegs.available(MRI, Reg))
10341031
return Reg;
10351032
}
10361033
return AArch64::NoRegister;
@@ -1046,11 +1043,14 @@ bool AArch64FrameLowering::canUseAsPrologue(
10461043
const AArch64FunctionInfo *AFI = MF->getInfo<AArch64FunctionInfo>();
10471044

10481045
if (AFI->hasSwiftAsyncContext()) {
1049-
LiveRegUnits LiveRegs(*RegInfo);
1046+
const AArch64RegisterInfo &TRI = *Subtarget.getRegisterInfo();
1047+
const MachineRegisterInfo &MRI = MF->getRegInfo();
1048+
LivePhysRegs LiveRegs(TRI);
10501049
getLiveRegsForEntryMBB(LiveRegs, MBB);
10511050
// The StoreSwiftAsyncContext clobbers X16 and X17. Make sure they are
10521051
// available.
1053-
if (!LiveRegs.available(AArch64::X16) || !LiveRegs.available(AArch64::X17))
1052+
if (!LiveRegs.available(MRI, AArch64::X16) ||
1053+
!LiveRegs.available(MRI, AArch64::X17))
10541054
return false;
10551055
}
10561056

@@ -1606,7 +1606,7 @@ static void emitDefineCFAWithFP(MachineFunction &MF, MachineBasicBlock &MBB,
16061606
/// Collect live registers from the end of \p MI's parent up to (including) \p
16071607
/// MI in \p LiveRegs.
16081608
static void getLivePhysRegsUpTo(MachineInstr &MI, const TargetRegisterInfo &TRI,
1609-
LiveRegUnits &LiveRegs) {
1609+
LivePhysRegs &LiveRegs) {
16101610

16111611
MachineBasicBlock &MBB = *MI.getParent();
16121612
LiveRegs.addLiveOuts(MBB);
@@ -1644,7 +1644,7 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
16441644
NonFrameStart->getFlag(MachineInstr::FrameSetup))
16451645
++NonFrameStart;
16461646

1647-
LiveRegUnits LiveRegs(*TRI);
1647+
LivePhysRegs LiveRegs(*TRI);
16481648
if (NonFrameStart != MBB.end()) {
16491649
getLivePhysRegsUpTo(*NonFrameStart, *TRI, LiveRegs);
16501650
// Ignore registers used for stack management for now.
@@ -1662,7 +1662,7 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
16621662
make_range(MBB.instr_begin(), NonFrameStart->getIterator())) {
16631663
for (auto &Op : MI.operands())
16641664
if (Op.isReg() && Op.isDef())
1665-
assert(LiveRegs.available(Op.getReg()) &&
1665+
assert(!LiveRegs.contains(Op.getReg()) &&
16661666
"live register clobbered by inserted prologue instructions");
16671667
}
16681668
});
@@ -4132,7 +4132,7 @@ MachineBasicBlock::iterator tryMergeAdjacentSTG(MachineBasicBlock::iterator II,
41324132
// FIXME : This approach of bailing out from merge is conservative in
41334133
// some ways like even if stg loops are not present after merge the
41344134
// insert list, this liveness check is done (which is not needed).
4135-
LiveRegUnits LiveRegs(*(MBB->getParent()->getSubtarget().getRegisterInfo()));
4135+
LivePhysRegs LiveRegs(*(MBB->getParent()->getSubtarget().getRegisterInfo()));
41364136
LiveRegs.addLiveOuts(*MBB);
41374137
for (auto I = MBB->rbegin();; ++I) {
41384138
MachineInstr &MI = *I;
@@ -4141,7 +4141,7 @@ MachineBasicBlock::iterator tryMergeAdjacentSTG(MachineBasicBlock::iterator II,
41414141
LiveRegs.stepBackward(*I);
41424142
}
41434143
InsertI++;
4144-
if (!LiveRegs.available(AArch64::NZCV))
4144+
if (LiveRegs.contains(AArch64::NZCV))
41454145
return InsertI;
41464146

41474147
llvm::stable_sort(Instrs,

llvm/lib/Target/ARM/ARMConstantIslandPass.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1025,7 +1025,10 @@ MachineBasicBlock *ARMConstantIslands::splitBlockBeforeInstr(MachineInstr *MI) {
10251025
OrigBB->addSuccessor(NewBB);
10261026

10271027
// Update live-in information in the new block.
1028-
addLiveIns(*NewBB, LRs);
1028+
MachineRegisterInfo &MRI = MF->getRegInfo();
1029+
for (MCPhysReg L : LRs)
1030+
if (!MRI.isReserved(L))
1031+
NewBB->addLiveIn(L);
10291032

10301033
// Update internal data structures to account for the newly inserted MBB.
10311034
// This is almost the same as updateForInsertedWaterBlock, except that

llvm/lib/Target/PowerPC/PPCMergeStringPool.cpp

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -302,13 +302,6 @@ bool PPCMergeStringPool::mergeModuleStringPool(Module &M) {
302302
return true;
303303
}
304304

305-
static bool userHasOperand(User *TheUser, GlobalVariable *GVOperand) {
306-
for (Value *Op : TheUser->operands())
307-
if (Op == GVOperand)
308-
return true;
309-
return false;
310-
}
311-
312305
// For pooled strings we need to add the offset into the pool for each string.
313306
// This is done by adding a Get Element Pointer (GEP) before each user. This
314307
// function adds the GEP.
@@ -319,29 +312,13 @@ void PPCMergeStringPool::replaceUsesWithGEP(GlobalVariable *GlobalToReplace,
319312
Indices.push_back(ConstantInt::get(Type::getInt32Ty(*Context), 0));
320313
Indices.push_back(ConstantInt::get(Type::getInt32Ty(*Context), ElementIndex));
321314

322-
// Need to save a temporary copy of each user list because we remove uses
323-
// as we replace them.
324-
SmallVector<User *> Users;
325-
for (User *CurrentUser : GlobalToReplace->users())
326-
Users.push_back(CurrentUser);
327-
328-
for (User *CurrentUser : Users) {
329-
// The user was not found so it must have been replaced earlier.
330-
if (!userHasOperand(CurrentUser, GlobalToReplace))
331-
continue;
332-
333-
// We cannot replace operands in globals so we ignore those.
334-
if (isa<GlobalValue>(CurrentUser))
335-
continue;
336-
337-
Constant *ConstGEP = ConstantExpr::getInBoundsGetElementPtr(
338-
PooledStructType, GPool, Indices);
339-
LLVM_DEBUG(dbgs() << "Replacing this global:\n");
340-
LLVM_DEBUG(GlobalToReplace->dump());
341-
LLVM_DEBUG(dbgs() << "with this:\n");
342-
LLVM_DEBUG(ConstGEP->dump());
343-
GlobalToReplace->replaceAllUsesWith(ConstGEP);
344-
}
315+
Constant *ConstGEP =
316+
ConstantExpr::getInBoundsGetElementPtr(PooledStructType, GPool, Indices);
317+
LLVM_DEBUG(dbgs() << "Replacing this global:\n");
318+
LLVM_DEBUG(GlobalToReplace->dump());
319+
LLVM_DEBUG(dbgs() << "with this:\n");
320+
LLVM_DEBUG(ConstGEP->dump());
321+
GlobalToReplace->replaceAllUsesWith(ConstGEP);
345322
}
346323

347324
} // namespace

llvm/lib/Target/SystemZ/SystemZPostRewrite.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include "SystemZInstrInfo.h"
1818
#include "SystemZSubtarget.h"
1919
#include "llvm/ADT/Statistic.h"
20-
#include "llvm/CodeGen/LiveRegUnits.h"
20+
#include "llvm/CodeGen/LivePhysRegs.h"
2121
#include "llvm/CodeGen/MachineFunctionPass.h"
2222
#include "llvm/CodeGen/MachineInstrBuilder.h"
2323
using namespace llvm;
@@ -161,8 +161,7 @@ bool SystemZPostRewrite::expandCondMove(MachineBasicBlock &MBB,
161161
assert(DestReg == MI.getOperand(1).getReg() &&
162162
"Expected destination and first source operand to be the same.");
163163

164-
const TargetRegisterInfo &TRI = TII->getRegisterInfo();
165-
LiveRegUnits LiveRegs(TRI);
164+
LivePhysRegs LiveRegs(TII->getRegisterInfo());
166165
LiveRegs.addLiveOuts(MBB);
167166
for (auto I = std::prev(MBB.end()); I != MBBI; --I)
168167
LiveRegs.stepBackward(*I);
@@ -172,18 +171,15 @@ bool SystemZPostRewrite::expandCondMove(MachineBasicBlock &MBB,
172171
MF.insert(std::next(MachineFunction::iterator(MBB)), RestMBB);
173172
RestMBB->splice(RestMBB->begin(), &MBB, MI, MBB.end());
174173
RestMBB->transferSuccessors(&MBB);
175-
const BitVector &BV = TRI.getAllocatableSet(MF);
176-
for (Register Reg : BV.set_bits())
177-
if (!LiveRegs.available(Reg))
178-
RestMBB->addLiveIn(Reg);
174+
for (MCPhysReg R : LiveRegs)
175+
RestMBB->addLiveIn(R);
179176

180177
// Create a new block MoveMBB to hold the move instruction.
181178
MachineBasicBlock *MoveMBB = MF.CreateMachineBasicBlock(BB);
182179
MF.insert(std::next(MachineFunction::iterator(MBB)), MoveMBB);
183180
MoveMBB->addLiveIn(SrcReg);
184-
for (Register Reg : BV.set_bits())
185-
if (!LiveRegs.available(Reg))
186-
MoveMBB->addLiveIn(Reg);
181+
for (MCPhysReg R : LiveRegs)
182+
MoveMBB->addLiveIn(R);
187183

188184
// At the end of MBB, create a conditional branch to RestMBB if the
189185
// condition is false, otherwise fall through to MoveMBB.

0 commit comments

Comments
 (0)