61 changes: 19 additions & 42 deletions clang/lib/CodeGen/CGDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "ConstantEmitter.h"
#include "EHScopeStack.h"
#include "PatternInit.h"
#include "TargetInfo.h"
#include "clang/AST/ASTContext.h"
Expand Down Expand Up @@ -2202,27 +2201,6 @@ void CodeGenFunction::pushDestroy(CleanupKind cleanupKind, Address addr,
destroyer, useEHCleanupForArray);
}

// Pushes a destroy and defers its deactivation until its
// CleanupDeactivationScope is exited.
void CodeGenFunction::pushDestroyAndDeferDeactivation(
QualType::DestructionKind dtorKind, Address addr, QualType type) {
assert(dtorKind && "cannot push destructor for trivial type");

CleanupKind cleanupKind = getCleanupKind(dtorKind);
pushDestroyAndDeferDeactivation(
cleanupKind, addr, type, getDestroyer(dtorKind), cleanupKind & EHCleanup);
}

void CodeGenFunction::pushDestroyAndDeferDeactivation(
CleanupKind cleanupKind, Address addr, QualType type, Destroyer *destroyer,
bool useEHCleanupForArray) {
llvm::Instruction *DominatingIP =
Builder.CreateFlagLoad(llvm::Constant::getNullValue(Int8PtrTy));
pushDestroy(cleanupKind, addr, type, destroyer, useEHCleanupForArray);
DeferredDeactivationCleanupStack.push_back(
{EHStack.stable_begin(), DominatingIP});
}

void CodeGenFunction::pushStackRestore(CleanupKind Kind, Address SPMem) {
EHStack.pushCleanup<CallStackRestore>(Kind, SPMem);
}
Expand All @@ -2239,19 +2217,16 @@ void CodeGenFunction::pushLifetimeExtendedDestroy(CleanupKind cleanupKind,
// If we're not in a conditional branch, we don't need to bother generating a
// conditional cleanup.
if (!isInConditionalBranch()) {
// Push an EH-only cleanup for the object now.
// FIXME: When popping normal cleanups, we need to keep this EH cleanup
// around in case a temporary's destructor throws an exception.
if (cleanupKind & EHCleanup)
EHStack.pushCleanup<DestroyObject>(
static_cast<CleanupKind>(cleanupKind & ~NormalCleanup), addr, type,
destroyer, useEHCleanupForArray);

// Add the cleanup to the EHStack. After the full-expr, this would be
// deactivated before being popped from the stack.
pushDestroyAndDeferDeactivation(cleanupKind, addr, type, destroyer,
useEHCleanupForArray);

// Since this is lifetime-extended, push it once again to the EHStack after
// the full expression.
return pushCleanupAfterFullExprWithActiveFlag<DestroyObject>(
cleanupKind, Address::invalid(), addr, type, destroyer,
useEHCleanupForArray);
cleanupKind, Address::invalid(), addr, type, destroyer, useEHCleanupForArray);
}

// Otherwise, we should only destroy the object if it's been initialized.
Expand All @@ -2266,12 +2241,13 @@ void CodeGenFunction::pushLifetimeExtendedDestroy(CleanupKind cleanupKind,
Address ActiveFlag = createCleanupActiveFlag();
SavedType SavedAddr = saveValueInCond(addr);

pushCleanupAndDeferDeactivation<ConditionalCleanupType>(
cleanupKind, SavedAddr, type, destroyer, useEHCleanupForArray);
initFullExprCleanupWithFlag(ActiveFlag);
if (cleanupKind & EHCleanup) {
EHStack.pushCleanup<ConditionalCleanupType>(
static_cast<CleanupKind>(cleanupKind & ~NormalCleanup), SavedAddr, type,
destroyer, useEHCleanupForArray);
initFullExprCleanupWithFlag(ActiveFlag);
}

// Since this is lifetime-extended, push it once again to the EHStack after
// the full expression.
pushCleanupAfterFullExprWithActiveFlag<ConditionalCleanupType>(
cleanupKind, ActiveFlag, SavedAddr, type, destroyer,
useEHCleanupForArray);
Expand Down Expand Up @@ -2466,9 +2442,9 @@ namespace {
};
} // end anonymous namespace

/// pushIrregularPartialArrayCleanup - Push a NormalAndEHCleanup to
/// destroy already-constructed elements of the given array. The cleanup may be
/// popped with DeactivateCleanupBlock or PopCleanupBlock.
/// pushIrregularPartialArrayCleanup - Push an EH cleanup to destroy
/// already-constructed elements of the given array. The cleanup
/// may be popped with DeactivateCleanupBlock or PopCleanupBlock.
///
/// \param elementType - the immediate element type of the array;
/// possibly still an array type
Expand All @@ -2477,9 +2453,10 @@ void CodeGenFunction::pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin,
QualType elementType,
CharUnits elementAlign,
Destroyer *destroyer) {
pushFullExprCleanup<IrregularPartialArrayDestroy>(
NormalAndEHCleanup, arrayBegin, arrayEndPointer, elementType,
elementAlign, destroyer);
pushFullExprCleanup<IrregularPartialArrayDestroy>(EHCleanup,
arrayBegin, arrayEndPointer,
elementType, elementAlign,
destroyer);
}

/// pushRegularPartialArrayCleanup - Push an EH cleanup to destroy
Expand Down
12 changes: 3 additions & 9 deletions clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,16 +115,10 @@ RawAddress CodeGenFunction::CreateTempAlloca(llvm::Type *Ty, CharUnits Align,
llvm::AllocaInst *CodeGenFunction::CreateTempAlloca(llvm::Type *Ty,
const Twine &Name,
llvm::Value *ArraySize) {
llvm::AllocaInst *Alloca;
if (ArraySize)
Alloca = Builder.CreateAlloca(Ty, ArraySize, Name);
else
Alloca = new llvm::AllocaInst(Ty, CGM.getDataLayout().getAllocaAddrSpace(),
ArraySize, Name, AllocaInsertPt);
if (Allocas) {
Allocas->Add(Alloca);
}
return Alloca;
return Builder.CreateAlloca(Ty, ArraySize, Name);
return new llvm::AllocaInst(Ty, CGM.getDataLayout().getAllocaAddrSpace(),
ArraySize, Name, AllocaInsertPt);
}

/// CreateDefaultAlignTempAlloca - This creates an alloca with the
Expand Down
87 changes: 61 additions & 26 deletions clang/lib/CodeGen/CGExprAgg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "ConstantEmitter.h"
#include "EHScopeStack.h"
#include "TargetInfo.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
Expand All @@ -25,7 +24,6 @@
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
using namespace clang;
Expand Down Expand Up @@ -560,27 +558,24 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,
// For that, we'll need an EH cleanup.
QualType::DestructionKind dtorKind = elementType.isDestructedType();
Address endOfInit = Address::invalid();
CodeGenFunction::CleanupDeactivationScope deactivation(CGF);

if (dtorKind) {
CodeGenFunction::AllocaTrackerRAII allocaTracker(CGF);
EHScopeStack::stable_iterator cleanup;
llvm::Instruction *cleanupDominator = nullptr;
if (CGF.needsEHCleanup(dtorKind)) {
// In principle we could tell the cleanup where we are more
// directly, but the control flow can get so varied here that it
// would actually be quite complex. Therefore we go through an
// alloca.
llvm::Instruction *dominatingIP =
Builder.CreateFlagLoad(llvm::ConstantInt::getNullValue(CGF.Int8PtrTy));
endOfInit = CGF.CreateTempAlloca(begin->getType(), CGF.getPointerAlign(),
"arrayinit.endOfInit");
Builder.CreateStore(begin, endOfInit);
cleanupDominator = Builder.CreateStore(begin, endOfInit);
CGF.pushIrregularPartialArrayCleanup(begin, endOfInit, elementType,
elementAlign,
CGF.getDestroyer(dtorKind));
cast<EHCleanupScope>(*CGF.EHStack.find(CGF.EHStack.stable_begin()))
.AddAuxAllocas(allocaTracker.Take());
cleanup = CGF.EHStack.stable_begin();

CGF.DeferredDeactivationCleanupStack.push_back(
{CGF.EHStack.stable_begin(), dominatingIP});
// Otherwise, remember that we didn't need a cleanup.
} else {
dtorKind = QualType::DK_none;
}

llvm::Value *one = llvm::ConstantInt::get(CGF.SizeTy, 1);
Expand Down Expand Up @@ -676,6 +671,9 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,

CGF.EmitBlock(endBB);
}

// Leave the partial-array cleanup if we entered one.
if (dtorKind) CGF.DeactivateCleanupBlock(cleanup, cleanupDominator);
}

//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -1376,8 +1374,9 @@ AggExprEmitter::VisitLambdaExpr(LambdaExpr *E) {
LValue SlotLV = CGF.MakeAddrLValue(Slot.getAddress(), E->getType());

// We'll need to enter cleanup scopes in case any of the element
// initializers throws an exception or contains branch out of the expressions.
CodeGenFunction::CleanupDeactivationScope scope(CGF);
// initializers throws an exception.
SmallVector<EHScopeStack::stable_iterator, 16> Cleanups;
llvm::Instruction *CleanupDominator = nullptr;

CXXRecordDecl::field_iterator CurField = E->getLambdaClass()->field_begin();
for (LambdaExpr::const_capture_init_iterator i = E->capture_init_begin(),
Expand All @@ -1396,12 +1395,28 @@ AggExprEmitter::VisitLambdaExpr(LambdaExpr *E) {
if (QualType::DestructionKind DtorKind =
CurField->getType().isDestructedType()) {
assert(LV.isSimple());
if (DtorKind)
CGF.pushDestroyAndDeferDeactivation(
NormalAndEHCleanup, LV.getAddress(CGF), CurField->getType(),
CGF.getDestroyer(DtorKind), false);
if (CGF.needsEHCleanup(DtorKind)) {
if (!CleanupDominator)
CleanupDominator = CGF.Builder.CreateAlignedLoad(
CGF.Int8Ty,
llvm::Constant::getNullValue(CGF.Int8PtrTy),
CharUnits::One()); // placeholder

CGF.pushDestroy(EHCleanup, LV.getAddress(CGF), CurField->getType(),
CGF.getDestroyer(DtorKind), false);
Cleanups.push_back(CGF.EHStack.stable_begin());
}
}
}

// Deactivate all the partial cleanups in reverse order, which
// generally means popping them.
for (unsigned i = Cleanups.size(); i != 0; --i)
CGF.DeactivateCleanupBlock(Cleanups[i-1], CleanupDominator);

// Destroy the placeholder if we made one.
if (CleanupDominator)
CleanupDominator->eraseFromParent();
}

void AggExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
Expand Down Expand Up @@ -1690,7 +1705,14 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr(
// We'll need to enter cleanup scopes in case any of the element
// initializers throws an exception.
SmallVector<EHScopeStack::stable_iterator, 16> cleanups;
CodeGenFunction::CleanupDeactivationScope DeactivateCleanups(CGF);
llvm::Instruction *cleanupDominator = nullptr;
auto addCleanup = [&](const EHScopeStack::stable_iterator &cleanup) {
cleanups.push_back(cleanup);
if (!cleanupDominator) // create placeholder once needed
cleanupDominator = CGF.Builder.CreateAlignedLoad(
CGF.Int8Ty, llvm::Constant::getNullValue(CGF.Int8PtrTy),
CharUnits::One());
};

unsigned curInitIndex = 0;

Expand All @@ -1713,8 +1735,10 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr(
CGF.EmitAggExpr(InitExprs[curInitIndex++], AggSlot);

if (QualType::DestructionKind dtorKind =
Base.getType().isDestructedType())
CGF.pushDestroyAndDeferDeactivation(dtorKind, V, Base.getType());
Base.getType().isDestructedType()) {
CGF.pushDestroy(dtorKind, V, Base.getType());
addCleanup(CGF.EHStack.stable_begin());
}
}
}

Expand Down Expand Up @@ -1789,10 +1813,10 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr(
if (QualType::DestructionKind dtorKind
= field->getType().isDestructedType()) {
assert(LV.isSimple());
if (dtorKind) {
CGF.pushDestroyAndDeferDeactivation(
NormalAndEHCleanup, LV.getAddress(CGF), field->getType(),
CGF.getDestroyer(dtorKind), false);
if (CGF.needsEHCleanup(dtorKind)) {
CGF.pushDestroy(EHCleanup, LV.getAddress(CGF), field->getType(),
CGF.getDestroyer(dtorKind), false);
addCleanup(CGF.EHStack.stable_begin());
pushedCleanup = true;
}
}
Expand All @@ -1805,6 +1829,17 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr(
if (GEP->use_empty())
GEP->eraseFromParent();
}

// Deactivate all the partial cleanups in reverse order, which
// generally means popping them.
assert((cleanupDominator || cleanups.empty()) &&
"Missing cleanupDominator before deactivating cleanup blocks");
for (unsigned i = cleanups.size(); i != 0; --i)
CGF.DeactivateCleanupBlock(cleanups[i-1], cleanupDominator);

// Destroy the placeholder if we made one.
if (cleanupDominator)
cleanupDominator->eraseFromParent();
}

void AggExprEmitter::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E,
Expand Down
38 changes: 19 additions & 19 deletions clang/lib/CodeGen/CGExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1008,8 +1008,8 @@ void CodeGenFunction::EmitNewArrayInitializer(
const Expr *Init = E->getInitializer();
Address EndOfInit = Address::invalid();
QualType::DestructionKind DtorKind = ElementType.isDestructedType();
CleanupDeactivationScope deactivation(*this);
bool pushedCleanup = false;
EHScopeStack::stable_iterator Cleanup;
llvm::Instruction *CleanupDominator = nullptr;

CharUnits ElementSize = getContext().getTypeSizeInChars(ElementType);
CharUnits ElementAlign =
Expand Down Expand Up @@ -1105,24 +1105,19 @@ void CodeGenFunction::EmitNewArrayInitializer(
}

// Enter a partial-destruction Cleanup if necessary.
if (DtorKind) {
AllocaTrackerRAII AllocaTracker(*this);
if (needsEHCleanup(DtorKind)) {
// In principle we could tell the Cleanup where we are more
// directly, but the control flow can get so varied here that it
// would actually be quite complex. Therefore we go through an
// alloca.
llvm::Instruction *DominatingIP =
Builder.CreateFlagLoad(llvm::ConstantInt::getNullValue(Int8PtrTy));
EndOfInit = CreateTempAlloca(BeginPtr.getType(), getPointerAlign(),
"array.init.end");
CleanupDominator =
Builder.CreateStore(BeginPtr.emitRawPointer(*this), EndOfInit);
pushIrregularPartialArrayCleanup(BeginPtr.emitRawPointer(*this),
EndOfInit, ElementType, ElementAlign,
getDestroyer(DtorKind));
cast<EHCleanupScope>(*EHStack.find(EHStack.stable_begin()))
.AddAuxAllocas(AllocaTracker.Take());
DeferredDeactivationCleanupStack.push_back(
{EHStack.stable_begin(), DominatingIP});
pushedCleanup = true;
Cleanup = EHStack.stable_begin();
}

CharUnits StartAlign = CurPtr.getAlignment();
Expand Down Expand Up @@ -1169,6 +1164,9 @@ void CodeGenFunction::EmitNewArrayInitializer(
// initialization.
llvm::ConstantInt *ConstNum = dyn_cast<llvm::ConstantInt>(NumElements);
if (ConstNum && ConstNum->getZExtValue() <= InitListElements) {
// If there was a Cleanup, deactivate it.
if (CleanupDominator)
DeactivateCleanupBlock(Cleanup, CleanupDominator);
return;
}

Expand Down Expand Up @@ -1283,22 +1281,24 @@ void CodeGenFunction::EmitNewArrayInitializer(
Builder.CreateStore(CurPtr.emitRawPointer(*this), EndOfInit);

// Enter a partial-destruction Cleanup if necessary.
if (!pushedCleanup && needsEHCleanup(DtorKind)) {
llvm::Instruction *DominatingIP =
Builder.CreateFlagLoad(llvm::ConstantInt::getNullValue(Int8PtrTy));
pushRegularPartialArrayCleanup(BeginPtr.emitRawPointer(*this),
CurPtr.emitRawPointer(*this), ElementType,
if (!CleanupDominator && needsEHCleanup(DtorKind)) {
llvm::Value *BeginPtrRaw = BeginPtr.emitRawPointer(*this);
llvm::Value *CurPtrRaw = CurPtr.emitRawPointer(*this);
pushRegularPartialArrayCleanup(BeginPtrRaw, CurPtrRaw, ElementType,
ElementAlign, getDestroyer(DtorKind));
DeferredDeactivationCleanupStack.push_back(
{EHStack.stable_begin(), DominatingIP});
Cleanup = EHStack.stable_begin();
CleanupDominator = Builder.CreateUnreachable();
}

// Emit the initializer into this element.
StoreAnyExprIntoOneUnit(*this, Init, Init->getType(), CurPtr,
AggValueSlot::DoesNotOverlap);

// Leave the Cleanup if we entered one.
deactivation.ForceDeactivate();
if (CleanupDominator) {
DeactivateCleanupBlock(Cleanup, CleanupDominator);
CleanupDominator->eraseFromParent();
}

// Advance to the next element by adjusting the pointer type as necessary.
llvm::Value *NextPtr = Builder.CreateConstInBoundsGEP1_32(
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3466,7 +3466,7 @@ void CGOpenMPRuntimeGPU::processRequiresDirective(
case CudaArch::SM_20:
case CudaArch::SM_21:
case CudaArch::SM_30:
case CudaArch::SM_32:
case CudaArch::SM_32_:
case CudaArch::SM_35:
case CudaArch::SM_37:
case CudaArch::SM_50:
Expand Down
6 changes: 0 additions & 6 deletions clang/lib/CodeGen/CodeGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,6 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext)

CodeGenFunction::~CodeGenFunction() {
assert(LifetimeExtendedCleanupStack.empty() && "failed to emit a cleanup");
assert(DeferredDeactivationCleanupStack.empty() &&
"missed to deactivate a cleanup");

if (getLangOpts().OpenMP && CurFn)
CGM.getOpenMPRuntime().functionFinished(*this);
Expand Down Expand Up @@ -348,10 +346,6 @@ static void EmitIfUsed(CodeGenFunction &CGF, llvm::BasicBlock *BB) {
void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
assert(BreakContinueStack.empty() &&
"mismatched push/pop in break/continue stack!");
assert(LifetimeExtendedCleanupStack.empty() &&
"mismatched push/pop of cleanups in EHStack!");
assert(DeferredDeactivationCleanupStack.empty() &&
"mismatched activate/deactivate of cleanups!");

bool OnlySimpleReturnStmts = NumSimpleReturnExprs > 0
&& NumSimpleReturnExprs == NumReturnExprs
Expand Down
99 changes: 3 additions & 96 deletions clang/lib/CodeGen/CodeGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Debug.h"
#include "llvm/Transforms/Utils/SanitizerStats.h"
Expand Down Expand Up @@ -671,51 +670,6 @@ class CodeGenFunction : public CodeGenTypeCache {

EHScopeStack EHStack;
llvm::SmallVector<char, 256> LifetimeExtendedCleanupStack;

// A stack of cleanups which were added to EHStack but have to be deactivated
// later before being popped or emitted. These are usually deactivated on
// exiting a `CleanupDeactivationScope` scope. For instance, after a
// full-expr.
//
// These are specially useful for correctly emitting cleanups while
// encountering branches out of expression (through stmt-expr or coroutine
// suspensions).
struct DeferredDeactivateCleanup {
EHScopeStack::stable_iterator Cleanup;
llvm::Instruction *DominatingIP;
};
llvm::SmallVector<DeferredDeactivateCleanup> DeferredDeactivationCleanupStack;

// Enters a new scope for capturing cleanups which are deferred to be
// deactivated, all of which will be deactivated once the scope is exited.
struct CleanupDeactivationScope {
CodeGenFunction &CGF;
size_t OldDeactivateCleanupStackSize;
bool Deactivated;
CleanupDeactivationScope(CodeGenFunction &CGF)
: CGF(CGF), OldDeactivateCleanupStackSize(
CGF.DeferredDeactivationCleanupStack.size()),
Deactivated(false) {}

void ForceDeactivate() {
assert(!Deactivated && "Deactivating already deactivated scope");
auto &Stack = CGF.DeferredDeactivationCleanupStack;
for (size_t I = Stack.size(); I > OldDeactivateCleanupStackSize; I--) {
CGF.DeactivateCleanupBlock(Stack[I - 1].Cleanup,
Stack[I - 1].DominatingIP);
Stack[I - 1].DominatingIP->eraseFromParent();
}
Stack.resize(OldDeactivateCleanupStackSize);
Deactivated = true;
}

~CleanupDeactivationScope() {
if (Deactivated)
return;
ForceDeactivate();
}
};

llvm::SmallVector<const JumpDest *, 2> SEHTryEpilogueStack;

llvm::Instruction *CurrentFuncletPad = nullptr;
Expand Down Expand Up @@ -921,19 +875,6 @@ class CodeGenFunction : public CodeGenTypeCache {
new (Buffer + sizeof(Header) + sizeof(T)) RawAddress(ActiveFlag);
}

// Push a cleanup onto EHStack and deactivate it later. It is usually
// deactivated when exiting a `CleanupDeactivationScope` (for example: after a
// full expression).
template <class T, class... As>
void pushCleanupAndDeferDeactivation(CleanupKind Kind, As... A) {
// Placeholder dominating IP for this cleanup.
llvm::Instruction *DominatingIP =
Builder.CreateFlagLoad(llvm::Constant::getNullValue(Int8PtrTy));
EHStack.pushCleanup<T>(Kind, A...);
DeferredDeactivationCleanupStack.push_back(
{EHStack.stable_begin(), DominatingIP});
}

/// Set up the last cleanup that was pushed as a conditional
/// full-expression cleanup.
void initFullExprCleanup() {
Expand All @@ -957,8 +898,7 @@ class CodeGenFunction : public CodeGenTypeCache {

/// PopCleanupBlock - Will pop the cleanup entry on the stack and
/// process all branch fixups.
void PopCleanupBlock(bool FallThroughIsBranchThrough = false,
bool ForDeactivation = false);
void PopCleanupBlock(bool FallThroughIsBranchThrough = false);

/// DeactivateCleanupBlock - Deactivates the given cleanup block.
/// The block cannot be reactivated. Pops it if it's the top of the
Expand Down Expand Up @@ -986,7 +926,6 @@ class CodeGenFunction : public CodeGenTypeCache {
class RunCleanupsScope {
EHScopeStack::stable_iterator CleanupStackDepth, OldCleanupScopeDepth;
size_t LifetimeExtendedCleanupStackSize;
CleanupDeactivationScope DeactivateCleanups;
bool OldDidCallStackSave;
protected:
bool PerformCleanup;
Expand All @@ -1001,7 +940,8 @@ class CodeGenFunction : public CodeGenTypeCache {
public:
/// Enter a new cleanup scope.
explicit RunCleanupsScope(CodeGenFunction &CGF)
: DeactivateCleanups(CGF), PerformCleanup(true), CGF(CGF) {
: PerformCleanup(true), CGF(CGF)
{
CleanupStackDepth = CGF.EHStack.stable_begin();
LifetimeExtendedCleanupStackSize =
CGF.LifetimeExtendedCleanupStack.size();
Expand Down Expand Up @@ -1031,7 +971,6 @@ class CodeGenFunction : public CodeGenTypeCache {
void ForceCleanup(std::initializer_list<llvm::Value**> ValuesToReload = {}) {
assert(PerformCleanup && "Already forced cleanup");
CGF.DidCallStackSave = OldDidCallStackSave;
DeactivateCleanups.ForceDeactivate();
CGF.PopCleanupBlocks(CleanupStackDepth, LifetimeExtendedCleanupStackSize,
ValuesToReload);
PerformCleanup = false;
Expand Down Expand Up @@ -2221,11 +2160,6 @@ class CodeGenFunction : public CodeGenTypeCache {
Address addr, QualType type);
void pushDestroy(CleanupKind kind, Address addr, QualType type,
Destroyer *destroyer, bool useEHCleanupForArray);
void pushDestroyAndDeferDeactivation(QualType::DestructionKind dtorKind,
Address addr, QualType type);
void pushDestroyAndDeferDeactivation(CleanupKind cleanupKind, Address addr,
QualType type, Destroyer *destroyer,
bool useEHCleanupForArray);
void pushLifetimeExtendedDestroy(CleanupKind kind, Address addr,
QualType type, Destroyer *destroyer,
bool useEHCleanupForArray);
Expand Down Expand Up @@ -2764,33 +2698,6 @@ class CodeGenFunction : public CodeGenTypeCache {
TBAAAccessInfo *TBAAInfo = nullptr);
LValue EmitLoadOfPointerLValue(Address Ptr, const PointerType *PtrTy);

private:
struct AllocaTracker {
void Add(llvm::AllocaInst *I) { Allocas.push_back(I); }
llvm::SmallVector<llvm::AllocaInst *> Take() { return std::move(Allocas); }

private:
llvm::SmallVector<llvm::AllocaInst *> Allocas;
};
AllocaTracker *Allocas = nullptr;

public:
// Captures all the allocas created during the scope of its RAII object.
struct AllocaTrackerRAII {
AllocaTrackerRAII(CodeGenFunction &CGF)
: CGF(CGF), OldTracker(CGF.Allocas) {
CGF.Allocas = &Tracker;
}
~AllocaTrackerRAII() { CGF.Allocas = OldTracker; }

llvm::SmallVector<llvm::AllocaInst *> Take() { return Tracker.Take(); }

private:
CodeGenFunction &CGF;
AllocaTracker *OldTracker;
AllocaTracker Tracker;
};

/// CreateTempAlloca - This creates an alloca and inserts it into the entry
/// block if \p ArraySize is nullptr, otherwise inserts it at the current
/// insertion point of the builder. The caller is responsible for setting an
Expand Down
16 changes: 11 additions & 5 deletions clang/lib/Driver/ToolChains/Arch/RISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,10 @@ static void getRISCFeaturesFromMcpu(const Driver &D, const Arg *A,
<< A->getSpelling() << Mcpu;
}

if (llvm::RISCV::hasFastUnalignedAccess(Mcpu))
Features.push_back("+fast-unaligned-access");
if (llvm::RISCV::hasFastUnalignedAccess(Mcpu)) {
Features.push_back("+unaligned-scalar-mem");
Features.push_back("+unaligned-vector-mem");
}
}

void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,
Expand Down Expand Up @@ -168,12 +170,16 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,
}

// Android requires fast unaligned access on RISCV64.
if (Triple.isAndroid())
Features.push_back("+fast-unaligned-access");
if (Triple.isAndroid()) {
Features.push_back("+unaligned-scalar-mem");
Features.push_back("+unaligned-vector-mem");
}

// -mstrict-align is default, unless -mno-strict-align is specified.
AddTargetFeature(Args, Features, options::OPT_mno_strict_align,
options::OPT_mstrict_align, "fast-unaligned-access");
options::OPT_mstrict_align, "unaligned-scalar-mem");
AddTargetFeature(Args, Features, options::OPT_mno_strict_align,
options::OPT_mstrict_align, "unaligned-vector-mem");

// Now add any that the user explicitly requested on the command line,
// which may override the defaults.
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaCUDA.h"
#include "clang/Sema/SemaDiagnostic.h"
#include "clang/Sema/SemaOpenMP.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
Expand Down Expand Up @@ -2383,7 +2384,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
}

if (getLangOpts().OpenMP)
Actions.startOpenMPCXXRangeFor();
Actions.OpenMP().startOpenMPCXXRangeFor();
if (Tok.is(tok::l_brace))
FRI->RangeExpr = ParseBraceInitializer();
else
Expand Down Expand Up @@ -5330,7 +5331,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,

stripTypeAttributesOffDeclSpec(attrs, DS, TUK);

Sema::SkipBodyInfo SkipBody;
SkipBodyInfo SkipBody;
if (!Name && TUK == Sema::TUK_Definition && Tok.is(tok::l_brace) &&
NextToken().is(tok::identifier))
SkipBody = Actions.shouldSkipAnonEnumBody(getCurScope(),
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Parse/ParseDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2092,7 +2092,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
TypeResult TypeResult = true; // invalid

bool Owned = false;
Sema::SkipBodyInfo SkipBody;
SkipBodyInfo SkipBody;
if (TemplateId) {
// Explicit specialization, class template partial specialization,
// or explicit instantiation.
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/Parse/ParseExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaCUDA.h"
#include "clang/Sema/SemaOpenMP.h"
#include "clang/Sema/SemaSYCL.h"
#include "clang/Sema/TypoCorrection.h"
#include "llvm/ADT/SmallVector.h"
Expand Down Expand Up @@ -2075,7 +2076,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
// replace this call to ActOnOpenACCArraySectionExpr in the future.
// Eventually we'll genericize the OPenMPArraySectionExpr type as
// well.
LHS = Actions.ActOnOMPArraySectionExpr(
LHS = Actions.OpenMP().ActOnOMPArraySectionExpr(
LHS.get(), Loc, ArgExprs.empty() ? nullptr : ArgExprs[0],
ColonLocFirst, ColonLocSecond, Length.get(), Stride.get(), RLoc);
} else {
Expand Down Expand Up @@ -3277,7 +3278,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
if (ErrorFound) {
Result = ExprError();
} else if (!Result.isInvalid()) {
Result = Actions.ActOnOMPArrayShapingExpr(
Result = Actions.OpenMP().ActOnOMPArrayShapingExpr(
Result.get(), OpenLoc, RParenLoc, OMPDimensions, OMPBracketsRanges);
}
return Result;
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Parse/ParseObjc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
Actions.ActOnTypedefedProtocols(protocols, protocolLocs,
superClassId, superClassLoc);

Sema::SkipBodyInfo SkipBody;
SkipBodyInfo SkipBody;
ObjCInterfaceDecl *ClsType = Actions.ActOnStartClassInterface(
getCurScope(), AtLoc, nameId, nameLoc, typeParameterList, superClassId,
superClassLoc, typeArgs,
Expand Down Expand Up @@ -2133,7 +2133,7 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
/*consumeLastToken=*/true))
return nullptr;

Sema::SkipBodyInfo SkipBody;
SkipBodyInfo SkipBody;
ObjCProtocolDecl *ProtoType = Actions.ActOnStartProtocolInterface(
AtLoc, protocolName, nameLoc, ProtocolRefs.data(), ProtocolRefs.size(),
ProtocolLocs.data(), EndProtoLoc, attrs, &SkipBody);
Expand Down
16 changes: 11 additions & 5 deletions clang/lib/Parse/ParseOpenACC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -835,19 +835,23 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams(
case OpenACCClauseKind::Default: {
Token DefKindTok = getCurToken();

if (expectIdentifierOrKeyword(*this))
break;
if (expectIdentifierOrKeyword(*this)) {
Parens.skipToEnd();
return OpenACCCanContinue();
}

ConsumeToken();

OpenACCDefaultClauseKind DefKind =
getOpenACCDefaultClauseKind(DefKindTok);

if (DefKind == OpenACCDefaultClauseKind::Invalid)
if (DefKind == OpenACCDefaultClauseKind::Invalid) {
Diag(DefKindTok, diag::err_acc_invalid_default_clause_kind);
else
ParsedClause.setDefaultDetails(DefKind);
Parens.skipToEnd();
return OpenACCCanContinue();
}

ParsedClause.setDefaultDetails(DefKind);
break;
}
case OpenACCClauseKind::If: {
Expand Down Expand Up @@ -977,6 +981,8 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams(
case OpenACCClauseKind::Self: {
assert(DirKind != OpenACCDirectiveKind::Update);
ExprResult CondExpr = ParseOpenACCConditionExpr();
ParsedClause.setConditionDetails(CondExpr.isUsable() ? CondExpr.get()
: nullptr);

if (CondExpr.isInvalid()) {
Parens.skipToEnd();
Expand Down
240 changes: 128 additions & 112 deletions clang/lib/Parse/ParseOpenMP.cpp

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion clang/lib/Parse/ParseStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/EnterExpressionEvaluationContext.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaOpenMP.h"
#include "clang/Sema/TypoCorrection.h"
#include "llvm/ADT/STLExtras.h"
#include <optional>
Expand Down Expand Up @@ -2301,7 +2302,7 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
// In OpenMP loop region loop control variable must be captured and be
// private. Perform analysis of first part (if any).
if (getLangOpts().OpenMP && FirstPart.isUsable()) {
Actions.ActOnOpenMPLoopInitialization(ForLoc, FirstPart.get());
Actions.OpenMP().ActOnOpenMPLoopInitialization(ForLoc, FirstPart.get());
}
}

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Parse/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1441,7 +1441,7 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,

// Tell the actions module that we have entered a function definition with the
// specified Declarator for the function.
Sema::SkipBodyInfo SkipBody;
SkipBodyInfo SkipBody;
Decl *Res = Actions.ActOnStartOfFunctionDef(getCurScope(), D,
TemplateInfo.TemplateParams
? *TemplateInfo.TemplateParams
Expand Down
25 changes: 14 additions & 11 deletions clang/lib/Sema/Sema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include "clang/Sema/SemaHLSL.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/SemaOpenACC.h"
#include "clang/Sema/SemaOpenMP.h"
#include "clang/Sema/SemaSYCL.h"
#include "clang/Sema/TemplateDeduction.h"
#include "clang/Sema/TemplateInstCallback.h"
Expand Down Expand Up @@ -203,6 +204,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
CUDAPtr(std::make_unique<SemaCUDA>(*this)),
HLSLPtr(std::make_unique<SemaHLSL>(*this)),
OpenACCPtr(std::make_unique<SemaOpenACC>(*this)),
OpenMPPtr(std::make_unique<SemaOpenMP>(*this)),
SYCLPtr(std::make_unique<SemaSYCL>(*this)),
MSPointerToMemberRepresentationMethod(
LangOpts.getMSPointerToMemberRepresentationMethod()),
Expand All @@ -226,8 +228,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
StringWithUTF8StringMethod(nullptr),
ValueWithBytesObjCTypeMethod(nullptr), NSArrayDecl(nullptr),
ArrayWithObjectsMethod(nullptr), NSDictionaryDecl(nullptr),
DictionaryWithObjectsMethod(nullptr), CodeCompleter(CodeCompleter),
VarDataSharingAttributesStack(nullptr) {
DictionaryWithObjectsMethod(nullptr), CodeCompleter(CodeCompleter) {
assert(pp.TUKind == TUKind);
TUScope = nullptr;

Expand All @@ -252,7 +253,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
nullptr, ExpressionEvaluationContextRecord::EK_Other);

// Initialization of data sharing attributes stack for OpenMP
InitDataSharingAttributesStack();
OpenMP().InitDataSharingAttributesStack();

std::unique_ptr<sema::SemaPPCallbacks> Callbacks =
std::make_unique<sema::SemaPPCallbacks>();
Expand Down Expand Up @@ -501,7 +502,7 @@ Sema::~Sema() {
threadSafety::threadSafetyCleanup(ThreadSafetyDeclCache);

// Destroys data sharing attributes stack for OpenMP
DestroyDataSharingAttributesStack();
OpenMP().DestroyDataSharingAttributesStack();

// Detach from the PP callback handler which outlives Sema since it's owned
// by the preprocessor.
Expand Down Expand Up @@ -1159,7 +1160,7 @@ void Sema::ActOnEndOfTranslationUnit() {

DiagnoseUnterminatedPragmaAlignPack();
DiagnoseUnterminatedPragmaAttribute();
DiagnoseUnterminatedOpenMPDeclareTarget();
OpenMP().DiagnoseUnterminatedOpenMPDeclareTarget();

// All delayed member exception specs should be checked or we end up accepting
// incompatible declarations.
Expand Down Expand Up @@ -1747,7 +1748,7 @@ class DeferredDiagnosticsEmitter
// Finalize analysis of OpenMP-specific constructs.
if (Caller && S.LangOpts.OpenMP && UsePath.size() == 1 &&
(ShouldEmitRootNode || InOMPDeviceContext))
S.finalizeOpenMPDelayedAnalysis(Caller, FD, Loc);
S.OpenMP().finalizeOpenMPDelayedAnalysis(Caller, FD, Loc);
if (Caller)
S.CUDA().DeviceKnownEmittedFns[FD] = {Caller, Loc};
// Always emit deferred diagnostics for the direct users. This does not
Expand Down Expand Up @@ -1899,8 +1900,8 @@ Sema::targetDiag(SourceLocation Loc, unsigned DiagID, const FunctionDecl *FD) {
FD = FD ? FD : getCurFunctionDecl();
if (LangOpts.OpenMP)
return LangOpts.OpenMPIsTargetDevice
? diagIfOpenMPDeviceCode(Loc, DiagID, FD)
: diagIfOpenMPHostCode(Loc, DiagID, FD);
? OpenMP().diagIfOpenMPDeviceCode(Loc, DiagID, FD)
: OpenMP().diagIfOpenMPHostCode(Loc, DiagID, FD);
if (getLangOpts().CUDA)
return getLangOpts().CUDAIsDevice ? CUDA().DiagIfDeviceCode(Loc, DiagID)
: CUDA().DiagIfHostCode(Loc, DiagID);
Expand Down Expand Up @@ -2131,7 +2132,7 @@ void Sema::PushFunctionScope() {
FunctionScopes.push_back(new FunctionScopeInfo(getDiagnostics()));
}
if (LangOpts.OpenMP)
pushOpenMPFunctionRegion();
OpenMP().pushOpenMPFunctionRegion();
}

void Sema::PushBlockScope(Scope *BlockScope, BlockDecl *Block) {
Expand Down Expand Up @@ -2251,7 +2252,7 @@ Sema::PopFunctionScopeInfo(const AnalysisBasedWarnings::Policy *WP,
PoppedFunctionScopeDeleter(this));

if (LangOpts.OpenMP)
popOpenMPFunctionRegion(Scope.get());
OpenMP().popOpenMPFunctionRegion(Scope.get());

// Issue any analysis-based warnings.
if (WP && D)
Expand Down Expand Up @@ -2687,7 +2688,9 @@ void Sema::PushCapturedRegionScope(Scope *S, CapturedDecl *CD, RecordDecl *RD,
unsigned OpenMPCaptureLevel) {
auto *CSI = new CapturedRegionScopeInfo(
getDiagnostics(), S, CD, RD, CD->getContextParam(), K,
(getLangOpts().OpenMP && K == CR_OpenMP) ? getOpenMPNestingLevel() : 0,
(getLangOpts().OpenMP && K == CR_OpenMP)
? OpenMP().getOpenMPNestingLevel()
: 0,
OpenMPCaptureLevel);
CSI->ReturnType = Context.VoidTy;
FunctionScopes.push_back(CSI);
Expand Down
73 changes: 35 additions & 38 deletions clang/lib/Sema/SemaCast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ namespace {
Self.CheckCastAlign(SrcExpr.get(), DestType, OpRange);
}

void checkObjCConversion(Sema::CheckedConversionKind CCK) {
void checkObjCConversion(CheckedConversionKind CCK) {
assert(Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers());

Expr *src = SrcExpr.get();
Expand Down Expand Up @@ -248,18 +248,14 @@ static TryCastResult TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExp
CastKind &Kind,
CXXCastPath &BasePath);

static TryCastResult TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr,
QualType DestType,
Sema::CheckedConversionKind CCK,
SourceRange OpRange,
unsigned &msg, CastKind &Kind,
bool ListInitialization);
static TryCastResult
TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
CheckedConversionKind CCK, SourceRange OpRange,
unsigned &msg, CastKind &Kind, bool ListInitialization);
static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr,
QualType DestType,
Sema::CheckedConversionKind CCK,
SourceRange OpRange,
unsigned &msg, CastKind &Kind,
CXXCastPath &BasePath,
QualType DestType, CheckedConversionKind CCK,
SourceRange OpRange, unsigned &msg,
CastKind &Kind, CXXCastPath &BasePath,
bool ListInitialization);
static TryCastResult TryConstCast(Sema &Self, ExprResult &SrcExpr,
QualType DestType, bool CStyle,
Expand Down Expand Up @@ -1223,7 +1219,7 @@ void CastOperation::CheckReinterpretCast() {

if (isValidCast(tcr)) {
if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())
checkObjCConversion(Sema::CCK_OtherCast);
checkObjCConversion(CheckedConversionKind::OtherCast);
DiagnoseReinterpretUpDownCast(Self, SrcExpr.get(), DestType, OpRange);

if (unsigned DiagID = checkCastFunctionType(Self, SrcExpr, DestType))
Expand Down Expand Up @@ -1274,9 +1270,9 @@ void CastOperation::CheckStaticCast() {
}

unsigned msg = diag::err_bad_cxx_cast_generic;
TryCastResult tcr
= TryStaticCast(Self, SrcExpr, DestType, Sema::CCK_OtherCast, OpRange, msg,
Kind, BasePath, /*ListInitialization=*/false);
TryCastResult tcr =
TryStaticCast(Self, SrcExpr, DestType, CheckedConversionKind::OtherCast,
OpRange, msg, Kind, BasePath, /*ListInitialization=*/false);
if (tcr != TC_Success && msg != 0) {
if (SrcExpr.isInvalid())
return;
Expand All @@ -1296,7 +1292,7 @@ void CastOperation::CheckStaticCast() {
if (Kind == CK_BitCast)
checkCastAlign();
if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())
checkObjCConversion(Sema::CCK_OtherCast);
checkObjCConversion(CheckedConversionKind::OtherCast);
} else {
SrcExpr = ExprError();
}
Expand All @@ -1317,14 +1313,13 @@ static bool IsAddressSpaceConversion(QualType SrcType, QualType DestType) {
/// possible. If @p CStyle, ignore access restrictions on hierarchy casting
/// and casting away constness.
static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr,
QualType DestType,
Sema::CheckedConversionKind CCK,
QualType DestType, CheckedConversionKind CCK,
SourceRange OpRange, unsigned &msg,
CastKind &Kind, CXXCastPath &BasePath,
bool ListInitialization) {
// Determine whether we have the semantics of a C-style cast.
bool CStyle
= (CCK == Sema::CCK_CStyleCast || CCK == Sema::CCK_FunctionalCast);
bool CStyle = (CCK == CheckedConversionKind::CStyleCast ||
CCK == CheckedConversionKind::FunctionalCast);

// The order the tests is not entirely arbitrary. There is one conversion
// that can be handled in two different ways. Given:
Expand Down Expand Up @@ -1884,11 +1879,11 @@ TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr, QualType SrcType,
///
/// An expression e can be explicitly converted to a type T using a
/// @c static_cast if the declaration "T t(e);" is well-formed [...].
TryCastResult
TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
Sema::CheckedConversionKind CCK,
SourceRange OpRange, unsigned &msg,
CastKind &Kind, bool ListInitialization) {
TryCastResult TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr,
QualType DestType,
CheckedConversionKind CCK,
SourceRange OpRange, unsigned &msg,
CastKind &Kind, bool ListInitialization) {
if (DestType->isRecordType()) {
if (Self.RequireCompleteType(OpRange.getBegin(), DestType,
diag::err_bad_cast_incomplete) ||
Expand All @@ -1900,13 +1895,14 @@ TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
}

InitializedEntity Entity = InitializedEntity::InitializeTemporary(DestType);
InitializationKind InitKind
= (CCK == Sema::CCK_CStyleCast)
? InitializationKind::CreateCStyleCast(OpRange.getBegin(), OpRange,
ListInitialization)
: (CCK == Sema::CCK_FunctionalCast)
? InitializationKind::CreateFunctionalCast(OpRange, ListInitialization)
: InitializationKind::CreateCast(OpRange);
InitializationKind InitKind =
(CCK == CheckedConversionKind::CStyleCast)
? InitializationKind::CreateCStyleCast(OpRange.getBegin(), OpRange,
ListInitialization)
: (CCK == CheckedConversionKind::FunctionalCast)
? InitializationKind::CreateFunctionalCast(OpRange,
ListInitialization)
: InitializationKind::CreateCast(OpRange);
Expr *SrcExprRaw = SrcExpr.get();
// FIXME: Per DR242, we should check for an implicit conversion sequence
// or for a constructor that could be invoked by direct-initialization
Expand All @@ -1918,8 +1914,8 @@ TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
// There is no other way that works.
// On the other hand, if we're checking a C-style cast, we've still got
// the reinterpret_cast way.
bool CStyle
= (CCK == Sema::CCK_CStyleCast || CCK == Sema::CCK_FunctionalCast);
bool CStyle = (CCK == CheckedConversionKind::CStyleCast ||
CCK == CheckedConversionKind::FunctionalCast);
if (InitSeq.Failed() && (CStyle || !DestType->isReferenceType()))
return TC_NotApplicable;

Expand Down Expand Up @@ -2814,8 +2810,9 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle,
if (isValidCast(tcr))
Kind = CK_NoOp;

Sema::CheckedConversionKind CCK =
FunctionalStyle ? Sema::CCK_FunctionalCast : Sema::CCK_CStyleCast;
CheckedConversionKind CCK = FunctionalStyle
? CheckedConversionKind::FunctionalCast
: CheckedConversionKind::CStyleCast;
if (tcr == TC_NotApplicable) {
tcr = TryAddressSpaceCast(Self, SrcExpr, DestType, /*CStyle*/ true, msg,
Kind);
Expand Down Expand Up @@ -3201,7 +3198,7 @@ void CastOperation::CheckCStyleCast() {

// ARC imposes extra restrictions on casts.
if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers()) {
checkObjCConversion(Sema::CCK_CStyleCast);
checkObjCConversion(CheckedConversionKind::CStyleCast);
if (SrcExpr.isInvalid())
return;

Expand Down
11 changes: 11 additions & 0 deletions clang/lib/Sema/SemaChecking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3233,6 +3233,17 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
if (BuiltinCountZeroBitsGeneric(*this, TheCall))
return ExprError();
break;

case Builtin::BI__builtin_allow_runtime_check: {
Expr *Arg = TheCall->getArg(0);
// Check if the argument is a string literal.
if (!isa<StringLiteral>(Arg->IgnoreParenImpCasts())) {
Diag(TheCall->getBeginLoc(), diag::err_expr_not_string_literal)
<< Arg->getSourceRange();
return ExprError();
}
break;
}
}

if (getLangOpts().HLSL && CheckHLSLBuiltinFunctionCall(BuiltinID, TheCall))
Expand Down
64 changes: 31 additions & 33 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include "clang/Sema/SemaCUDA.h"
#include "clang/Sema/SemaHLSL.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/SemaOpenMP.h"
#include "clang/Sema/Template.h"
#include "llvm/ADT/STLForwardCompat.h"
#include "llvm/ADT/SmallString.h"
Expand Down Expand Up @@ -3036,7 +3037,7 @@ static void checkNewAttributesAfterDef(Sema &S, Decl *New, const Decl *Old) {

if (isa<AliasAttr>(NewAttribute) || isa<IFuncAttr>(NewAttribute)) {
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(New)) {
Sema::SkipBodyInfo SkipBody;
SkipBodyInfo SkipBody;
S.CheckForFunctionRedefinition(FD, cast<FunctionDecl>(Def), &SkipBody);

// If we're skipping this definition, drop the "alias" attribute.
Expand Down Expand Up @@ -6168,11 +6169,12 @@ Decl *Sema::ActOnDeclarator(Scope *S, Declarator &D) {
// Check if we are in an `omp begin/end declare variant` scope. Handle this
// declaration only if the `bind_to_declaration` extension is set.
SmallVector<FunctionDecl *, 4> Bases;
if (LangOpts.OpenMP && isInOpenMPDeclareVariantScope())
if (getOMPTraitInfoForSurroundingScope()->isExtensionActive(llvm::omp::TraitProperty::
implementation_extension_bind_to_declaration))
ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
S, D, MultiTemplateParamsArg(), Bases);
if (LangOpts.OpenMP && OpenMP().isInOpenMPDeclareVariantScope())
if (OpenMP().getOMPTraitInfoForSurroundingScope()->isExtensionActive(
llvm::omp::TraitProperty::
implementation_extension_bind_to_declaration))
OpenMP().ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
S, D, MultiTemplateParamsArg(), Bases);

Decl *Dcl = HandleDeclarator(S, D, MultiTemplateParamsArg());

Expand All @@ -6181,7 +6183,8 @@ Decl *Sema::ActOnDeclarator(Scope *S, Declarator &D) {
Dcl->setTopLevelDeclInObjCContainer();

if (!Bases.empty())
ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Dcl, Bases);
OpenMP().ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Dcl,
Bases);

return Dcl;
}
Expand Down Expand Up @@ -6568,8 +6571,8 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D,
if (New->getDeclName() && AddToScope)
PushOnScopeChains(New, S);

if (isInOpenMPDeclareTargetContext())
checkDeclIsAllowedInOpenMPTarget(nullptr, New);
if (OpenMP().isInOpenMPDeclareTargetContext())
OpenMP().checkDeclIsAllowedInOpenMPTarget(nullptr, New);

return New;
}
Expand Down Expand Up @@ -12268,7 +12271,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
}

if (LangOpts.OpenMP)
ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(NewFD);
OpenMP().ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(NewFD);

// Semantic checking for this function declaration (in isolation).

Expand Down Expand Up @@ -12668,7 +12671,7 @@ void Sema::CheckMSVCRTEntryPoint(FunctionDecl *FD) {
}
}

bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) {
bool Sema::CheckForConstantInitializer(Expr *Init, unsigned DiagID) {
// FIXME: Need strict checking. In C89, we need to check for
// any assignment, increment, decrement, function-calls, or
// commas outside of a sizeof. In C99, it's the same list,
Expand All @@ -12686,8 +12689,7 @@ bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) {
const Expr *Culprit;
if (Init->isConstantInitializer(Context, false, &Culprit))
return false;
Diag(Culprit->getExprLoc(), diag::err_init_element_not_constant)
<< Culprit->getSourceRange();
Diag(Culprit->getExprLoc(), DiagID) << Culprit->getSourceRange();
return true;
}

Expand Down Expand Up @@ -13805,29 +13807,24 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
// OpenCL v1.2 s6.5.3: __constant locals must be constant-initialized.
// This is true even in C++ for OpenCL.
} else if (VDecl->getType().getAddressSpace() == LangAS::opencl_constant) {
CheckForConstantInitializer(Init, DclT);
CheckForConstantInitializer(Init);

// Otherwise, C++ does not restrict the initializer.
// Otherwise, C++ does not restrict the initializer.
} else if (getLangOpts().CPlusPlus) {
// do nothing

// C99 6.7.8p4: All the expressions in an initializer for an object that has
// static storage duration shall be constant expressions or string literals.
} else if (VDecl->getStorageClass() == SC_Static) {
CheckForConstantInitializer(Init, DclT);
CheckForConstantInitializer(Init);

// C89 is stricter than C99 for aggregate initializers.
// C89 6.5.7p3: All the expressions [...] in an initializer list
// for an object that has aggregate or union type shall be
// constant expressions.
// C89 is stricter than C99 for aggregate initializers.
// C89 6.5.7p3: All the expressions [...] in an initializer list
// for an object that has aggregate or union type shall be
// constant expressions.
} else if (!getLangOpts().C99 && VDecl->getType()->isAggregateType() &&
isa<InitListExpr>(Init)) {
const Expr *Culprit;
if (!Init->isConstantInitializer(Context, false, &Culprit)) {
Diag(Culprit->getExprLoc(),
diag::ext_aggregate_init_not_constant)
<< Culprit->getSourceRange();
}
CheckForConstantInitializer(Init, diag::ext_aggregate_init_not_constant);
}

if (auto *E = dyn_cast<ExprWithCleanups>(Init))
Expand Down Expand Up @@ -13960,7 +13957,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
// Avoid duplicate diagnostics for constexpr variables.
if (!getLangOpts().CPlusPlus && !VDecl->isInvalidDecl() &&
!VDecl->isConstexpr())
CheckForConstantInitializer(Init, DclT);
CheckForConstantInitializer(Init);
}

QualType InitType = Init->getType();
Expand Down Expand Up @@ -14956,7 +14953,7 @@ Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
if (auto *VD = dyn_cast<VarDecl>(D);
LangOpts.OpenMP && VD && VD->hasAttr<OMPDeclareTargetDeclAttr>() &&
VD->hasGlobalStorage())
ActOnOpenMPDeclareTargetInitializer(D);
OpenMP().ActOnOpenMPDeclareTargetInitializer(D);
// For declarators, there are some additional syntactic-ish checks we need
// to perform.
if (auto *DD = dyn_cast<DeclaratorDecl>(D)) {
Expand Down Expand Up @@ -15495,16 +15492,17 @@ Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D,
// specialization function under the OpenMP context defined as part of the
// `omp begin declare variant`.
SmallVector<FunctionDecl *, 4> Bases;
if (LangOpts.OpenMP && isInOpenMPDeclareVariantScope())
ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
if (LangOpts.OpenMP && OpenMP().isInOpenMPDeclareVariantScope())
OpenMP().ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
ParentScope, D, TemplateParameterLists, Bases);

D.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
Decl *DP = HandleDeclarator(ParentScope, D, TemplateParameterLists);
Decl *Dcl = ActOnStartOfFunctionDef(FnBodyScope, DP, SkipBody, BodyKind);

if (!Bases.empty())
ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Dcl, Bases);
OpenMP().ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Dcl,
Bases);

return Dcl;
}
Expand Down Expand Up @@ -20001,7 +19999,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
Val, EnumVal);
}

Sema::SkipBodyInfo Sema::shouldSkipAnonEnumBody(Scope *S, IdentifierInfo *II,
SkipBodyInfo Sema::shouldSkipAnonEnumBody(Scope *S, IdentifierInfo *II,
SourceLocation IILoc) {
if (!(getLangOpts().Modules || getLangOpts().ModulesLocalVisibility) ||
!getLangOpts().CPlusPlus)
Expand Down Expand Up @@ -20651,7 +20649,7 @@ Sema::FunctionEmissionStatus Sema::getEmissionStatus(const FunctionDecl *FD,
return FunctionEmissionStatus::OMPDiscarded;
// If we have an explicit value for the device type, or we are in a target
// declare context, we need to emit all extern and used symbols.
if (isInOpenMPDeclareTargetContext() || DevTy)
if (OpenMP().isInOpenMPDeclareTargetContext() || DevTy)
if (IsEmittedForExternalSymbol())
return FunctionEmissionStatus::Emitted;
// Device mode only emits what it must, if it wasn't tagged yet and needed,
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2001,6 +2001,8 @@ static void markUsedForAliasOrIfunc(Sema &S, Decl *D, const ParsedAttr &AL,
LookupResult LR(S, Target, Sema::LookupOrdinaryName);
if (S.LookupName(LR, S.TUScope)) {
for (NamedDecl *ND : LR) {
if (!isa<FunctionDecl>(ND) && !isa<VarDecl>(ND))
continue;
if (MC->shouldMangleDeclName(ND)) {
llvm::raw_svector_ostream Out(Name);
Name.clear();
Expand Down
9 changes: 5 additions & 4 deletions clang/lib/Sema/SemaDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaCUDA.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/SemaOpenMP.h"
#include "clang/Sema/Template.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
Expand Down Expand Up @@ -962,8 +963,8 @@ Sema::ActOnDecompositionDeclarator(Scope *S, Declarator &D,
CurContext->addHiddenDecl(New);
}

if (isInOpenMPDeclareTargetContext())
checkDeclIsAllowedInOpenMPTarget(nullptr, New);
if (OpenMP().isInOpenMPDeclareTargetContext())
OpenMP().checkDeclIsAllowedInOpenMPTarget(nullptr, New);

return New;
}
Expand Down Expand Up @@ -18654,8 +18655,8 @@ void Sema::MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class,
// Do not mark as used if compiling for the device outside of the target
// region.
if (TUKind != TU_Prefix && LangOpts.OpenMP && LangOpts.OpenMPIsTargetDevice &&
!isInOpenMPDeclareTargetContext() &&
!isInOpenMPTargetExecutionDirective()) {
!OpenMP().isInOpenMPDeclareTargetContext() &&
!OpenMP().isInOpenMPTargetExecutionDirective()) {
if (!DefinitionRequired)
MarkVirtualMembersReferenced(Loc, Class);
return;
Expand Down
622 changes: 38 additions & 584 deletions clang/lib/Sema/SemaExpr.cpp

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions clang/lib/Sema/SemaExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4250,7 +4250,8 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
AssignmentAction Action,
CheckedConversionKind CCK) {
// C++ [over.match.oper]p7: [...] operands of class type are converted [...]
if (CCK == CCK_ForBuiltinOverloadedOp && !From->getType()->isRecordType())
if (CCK == CheckedConversionKind::ForBuiltinOverloadedOp &&
!From->getType()->isRecordType())
return From;

switch (ICS.getKind()) {
Expand Down Expand Up @@ -4311,7 +4312,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
// C++ [over.match.oper]p7:
// [...] the second standard conversion sequence of a user-defined
// conversion sequence is not applied.
if (CCK == CCK_ForBuiltinOverloadedOp)
if (CCK == CheckedConversionKind::ForBuiltinOverloadedOp)
return From;

return PerformImplicitConversion(From, ToType, ICS.UserDefined.After,
Expand Down Expand Up @@ -4352,7 +4353,8 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
const StandardConversionSequence& SCS,
AssignmentAction Action,
CheckedConversionKind CCK) {
bool CStyle = (CCK == CCK_CStyleCast || CCK == CCK_FunctionalCast);
bool CStyle = (CCK == CheckedConversionKind::CStyleCast ||
CCK == CheckedConversionKind::FunctionalCast);

// Overall FIXME: we are recomputing too many types here and doing far too
// much extra work. What this means is that we need to keep track of more
Expand Down
9 changes: 5 additions & 4 deletions clang/lib/Sema/SemaExprMember.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
// This file implements semantic analysis member access expressions.
//
//===----------------------------------------------------------------------===//
#include "clang/Sema/Overload.h"
#include "clang/AST/ASTLambda.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
Expand All @@ -18,9 +17,11 @@
#include "clang/AST/ExprObjC.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Overload.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/SemaOpenMP.h"

using namespace clang;
using namespace sema;
Expand Down Expand Up @@ -1900,9 +1901,9 @@ Sema::BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow,
if (getLangOpts().OpenMP && IsArrow &&
!CurContext->isDependentContext() &&
isa<CXXThisExpr>(Base.get()->IgnoreParenImpCasts())) {
if (auto *PrivateCopy = isOpenMPCapturedDecl(Field)) {
return getOpenMPCapturedExpr(PrivateCopy, VK, OK,
MemberNameInfo.getLoc());
if (auto *PrivateCopy = OpenMP().isOpenMPCapturedDecl(Field)) {
return OpenMP().getOpenMPCapturedExpr(PrivateCopy, VK, OK,
MemberNameInfo.getLoc());
}
}

Expand Down
45 changes: 23 additions & 22 deletions clang/lib/Sema/SemaExprObjC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3745,22 +3745,22 @@ bool Sema::isKnownName(StringRef name) {

template <typename DiagBuilderT>
static void addFixitForObjCARCConversion(
Sema &S, DiagBuilderT &DiagB, Sema::CheckedConversionKind CCK,
Sema &S, DiagBuilderT &DiagB, CheckedConversionKind CCK,
SourceLocation afterLParen, QualType castType, Expr *castExpr,
Expr *realCast, const char *bridgeKeyword, const char *CFBridgeName) {
// We handle C-style and implicit casts here.
switch (CCK) {
case Sema::CCK_ImplicitConversion:
case Sema::CCK_ForBuiltinOverloadedOp:
case Sema::CCK_CStyleCast:
case Sema::CCK_OtherCast:
case CheckedConversionKind::Implicit:
case CheckedConversionKind::ForBuiltinOverloadedOp:
case CheckedConversionKind::CStyleCast:
case CheckedConversionKind::OtherCast:
break;
case Sema::CCK_FunctionalCast:
case CheckedConversionKind::FunctionalCast:
return;
}

if (CFBridgeName) {
if (CCK == Sema::CCK_OtherCast) {
if (CCK == CheckedConversionKind::OtherCast) {
if (const CXXNamedCastExpr *NCE = dyn_cast<CXXNamedCastExpr>(realCast)) {
SourceRange range(NCE->getOperatorLoc(),
NCE->getAngleBrackets().getEnd());
Expand Down Expand Up @@ -3805,9 +3805,9 @@ static void addFixitForObjCARCConversion(
return;
}

if (CCK == Sema::CCK_CStyleCast) {
if (CCK == CheckedConversionKind::CStyleCast) {
DiagB.AddFixItHint(FixItHint::CreateInsertion(afterLParen, bridgeKeyword));
} else if (CCK == Sema::CCK_OtherCast) {
} else if (CCK == CheckedConversionKind::OtherCast) {
if (const CXXNamedCastExpr *NCE = dyn_cast<CXXNamedCastExpr>(realCast)) {
std::string castCode = "(";
castCode += bridgeKeyword;
Expand Down Expand Up @@ -3866,12 +3866,12 @@ static ObjCBridgeRelatedAttr *ObjCBridgeRelatedAttrFromType(QualType T,
return nullptr;
}

static void
diagnoseObjCARCConversion(Sema &S, SourceRange castRange,
QualType castType, ARCConversionTypeClass castACTC,
Expr *castExpr, Expr *realCast,
ARCConversionTypeClass exprACTC,
Sema::CheckedConversionKind CCK) {
static void diagnoseObjCARCConversion(Sema &S, SourceRange castRange,
QualType castType,
ARCConversionTypeClass castACTC,
Expr *castExpr, Expr *realCast,
ARCConversionTypeClass exprACTC,
CheckedConversionKind CCK) {
SourceLocation loc =
(castRange.isValid() ? castRange.getBegin() : castExpr->getExprLoc());

Expand Down Expand Up @@ -3927,7 +3927,7 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange,
assert(CreateRule != ACC_bottom && "This cast should already be accepted.");
if (CreateRule != ACC_plusOne)
{
auto DiagB = (CCK != Sema::CCK_OtherCast)
auto DiagB = (CCK != CheckedConversionKind::OtherCast)
? S.Diag(noteLoc, diag::note_arc_bridge)
: S.Diag(noteLoc, diag::note_arc_cstyle_bridge);

Expand All @@ -3937,7 +3937,7 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange,
}
if (CreateRule != ACC_plusZero)
{
auto DiagB = (CCK == Sema::CCK_OtherCast && !br)
auto DiagB = (CCK == CheckedConversionKind::OtherCast && !br)
? S.Diag(noteLoc, diag::note_arc_cstyle_bridge_transfer)
<< castExprType
: S.Diag(br ? castExpr->getExprLoc() : noteLoc,
Expand Down Expand Up @@ -3968,7 +3968,7 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange,
assert(CreateRule != ACC_bottom && "This cast should already be accepted.");
if (CreateRule != ACC_plusOne)
{
auto DiagB = (CCK != Sema::CCK_OtherCast)
auto DiagB = (CCK != CheckedConversionKind::OtherCast)
? S.Diag(noteLoc, diag::note_arc_bridge)
: S.Diag(noteLoc, diag::note_arc_cstyle_bridge);
addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
Expand All @@ -3977,7 +3977,7 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange,
}
if (CreateRule != ACC_plusZero)
{
auto DiagB = (CCK == Sema::CCK_OtherCast && !br)
auto DiagB = (CCK == CheckedConversionKind::OtherCast && !br)
? S.Diag(noteLoc, diag::note_arc_cstyle_bridge_retained)
<< castType
: S.Diag(br ? castExpr->getExprLoc() : noteLoc,
Expand Down Expand Up @@ -4403,7 +4403,8 @@ Sema::CheckObjCConversion(SourceRange castRange, QualType castType,
// Check for viability and report error if casting an rvalue to a
// life-time qualifier.
if (castACTC == ACTC_retainable &&
(CCK == CCK_CStyleCast || CCK == CCK_OtherCast) &&
(CCK == CheckedConversionKind::CStyleCast ||
CCK == CheckedConversionKind::OtherCast) &&
castType != castExprType) {
const Type *DT = castType.getTypePtr();
QualType QDT = castType;
Expand Down Expand Up @@ -4517,11 +4518,11 @@ void Sema::diagnoseARCUnbridgedCast(Expr *e) {
if (CStyleCastExpr *cast = dyn_cast<CStyleCastExpr>(realCast)) {
castRange = SourceRange(cast->getLParenLoc(), cast->getRParenLoc());
castType = cast->getTypeAsWritten();
CCK = CCK_CStyleCast;
CCK = CheckedConversionKind::CStyleCast;
} else if (ExplicitCastExpr *cast = dyn_cast<ExplicitCastExpr>(realCast)) {
castRange = cast->getTypeInfoAsWritten()->getTypeLoc().getSourceRange();
castType = cast->getTypeAsWritten();
CCK = CCK_OtherCast;
CCK = CheckedConversionKind::OtherCast;
} else {
llvm_unreachable("Unexpected ImplicitCastExpr");
}
Expand Down
10 changes: 5 additions & 5 deletions clang/lib/Sema/SemaInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9057,11 +9057,11 @@ ExprResult InitializationSequence::Perform(Sema &S,
}
}

Sema::CheckedConversionKind CCK
= Kind.isCStyleCast()? Sema::CCK_CStyleCast
: Kind.isFunctionalCast()? Sema::CCK_FunctionalCast
: Kind.isExplicitCast()? Sema::CCK_OtherCast
: Sema::CCK_ImplicitConversion;
CheckedConversionKind CCK =
Kind.isCStyleCast() ? CheckedConversionKind::CStyleCast
: Kind.isFunctionalCast() ? CheckedConversionKind::FunctionalCast
: Kind.isExplicitCast() ? CheckedConversionKind::OtherCast
: CheckedConversionKind::Implicit;
ExprResult CurInitExprRes =
S.PerformImplicitConversion(CurInit.get(), Step->Type, *Step->ICS,
getAssignmentAction(Entity), CCK);
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Sema/SemaLambda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaCUDA.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/SemaOpenMP.h"
#include "clang/Sema/Template.h"
#include "llvm/ADT/STLExtras.h"
#include <optional>
Expand Down Expand Up @@ -1398,7 +1399,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,

// OpenMP lambdas might get assumumption attributes.
if (LangOpts.OpenMP)
ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Method);
OpenMP().ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Method);

handleLambdaNumbering(Class, Method);

Expand Down
68 changes: 60 additions & 8 deletions clang/lib/Sema/SemaOpenACC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "clang/AST/StmtOpenACC.h"
#include "clang/Basic/DiagnosticSema.h"
#include "clang/Sema/Sema.h"
#include "llvm/Support/Casting.h"

using namespace clang;

Expand Down Expand Up @@ -76,6 +77,19 @@ bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind,
default:
return false;
}
case OpenACCClauseKind::Self:
switch (DirectiveKind) {
case OpenACCDirectiveKind::Parallel:
case OpenACCDirectiveKind::Serial:
case OpenACCDirectiveKind::Kernels:
case OpenACCDirectiveKind::Update:
case OpenACCDirectiveKind::ParallelLoop:
case OpenACCDirectiveKind::SerialLoop:
case OpenACCDirectiveKind::KernelsLoop:
return true;
default:
return false;
}
default:
// Do nothing so we can go to the 'unimplemented' diagnostic instead.
return true;
Expand Down Expand Up @@ -121,9 +135,7 @@ SemaOpenACC::ActOnClause(ArrayRef<const OpenACCClause *> ExistingClauses,
// Restrictions only properly implemented on 'compute' constructs, and
// 'compute' constructs are the only construct that can do anything with
// this yet, so skip/treat as unimplemented in this case.
if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Parallel &&
Clause.getDirectiveKind() != OpenACCDirectiveKind::Serial &&
Clause.getDirectiveKind() != OpenACCDirectiveKind::Kernels)
if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
break;

// Don't add an invalid clause to the AST.
Expand All @@ -146,9 +158,7 @@ SemaOpenACC::ActOnClause(ArrayRef<const OpenACCClause *> ExistingClauses,
// Restrictions only properly implemented on 'compute' constructs, and
// 'compute' constructs are the only construct that can do anything with
// this yet, so skip/treat as unimplemented in this case.
if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Parallel &&
Clause.getDirectiveKind() != OpenACCDirectiveKind::Serial &&
Clause.getDirectiveKind() != OpenACCDirectiveKind::Kernels)
if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
break;

// There is no prose in the standard that says duplicates aren't allowed,
Expand All @@ -160,12 +170,54 @@ SemaOpenACC::ActOnClause(ArrayRef<const OpenACCClause *> ExistingClauses,
// The parser has ensured that we have a proper condition expr, so there
// isn't really much to do here.

// TODO OpenACC: When we implement 'self', this clauses causes us to
// 'ignore' the self clause, so we should implement a warning here.
// If the 'if' clause is true, it makes the 'self' clause have no effect,
// diagnose that here.
// TODO OpenACC: When we add these two to other constructs, we might not
// want to warn on this (for example, 'update').
const auto *Itr =
llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCSelfClause>);
if (Itr != ExistingClauses.end()) {
Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict);
Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
}

return OpenACCIfClause::Create(
getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(),
Clause.getConditionExpr(), Clause.getEndLoc());
}

case OpenACCClauseKind::Self: {
// Restrictions only properly implemented on 'compute' constructs, and
// 'compute' constructs are the only construct that can do anything with
// this yet, so skip/treat as unimplemented in this case.
if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
break;

// TODO OpenACC: When we implement this for 'update', this takes a
// 'var-list' instead of a condition expression, so semantics/handling has
// to happen differently here.

// There is no prose in the standard that says duplicates aren't allowed,
// but this diagnostic is present in other compilers, as well as makes
// sense.
if (checkAlreadyHasClauseOfKind(*this, ExistingClauses, Clause))
return nullptr;

// If the 'if' clause is true, it makes the 'self' clause have no effect,
// diagnose that here.
// TODO OpenACC: When we add these two to other constructs, we might not
// want to warn on this (for example, 'update').
const auto *Itr =
llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCIfClause>);
if (Itr != ExistingClauses.end()) {
Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict);
Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
}

return OpenACCSelfClause::Create(
getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(),
Clause.getConditionExpr(), Clause.getEndLoc());
}
default:
break;
}
Expand Down
4,333 changes: 2,506 additions & 1,827 deletions clang/lib/Sema/SemaOpenMP.cpp

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions clang/lib/Sema/SemaOverload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14506,7 +14506,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,
// operator node.
ExprResult InputRes = PerformImplicitConversion(
Input, Best->BuiltinParamTypes[0], Best->Conversions[0], AA_Passing,
CCK_ForBuiltinOverloadedOp);
CheckedConversionKind::ForBuiltinOverloadedOp);
if (InputRes.isInvalid())
return ExprError();
Input = InputRes.get();
Expand Down Expand Up @@ -14989,14 +14989,14 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
// operator node.
ExprResult ArgsRes0 = PerformImplicitConversion(
Args[0], Best->BuiltinParamTypes[0], Best->Conversions[0],
AA_Passing, CCK_ForBuiltinOverloadedOp);
AA_Passing, CheckedConversionKind::ForBuiltinOverloadedOp);
if (ArgsRes0.isInvalid())
return ExprError();
Args[0] = ArgsRes0.get();

ExprResult ArgsRes1 = PerformImplicitConversion(
Args[1], Best->BuiltinParamTypes[1], Best->Conversions[1],
AA_Passing, CCK_ForBuiltinOverloadedOp);
AA_Passing, CheckedConversionKind::ForBuiltinOverloadedOp);
if (ArgsRes1.isInvalid())
return ExprError();
Args[1] = ArgsRes1.get();
Expand Down Expand Up @@ -15367,14 +15367,14 @@ ExprResult Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
// operator node.
ExprResult ArgsRes0 = PerformImplicitConversion(
Args[0], Best->BuiltinParamTypes[0], Best->Conversions[0],
AA_Passing, CCK_ForBuiltinOverloadedOp);
AA_Passing, CheckedConversionKind::ForBuiltinOverloadedOp);
if (ArgsRes0.isInvalid())
return ExprError();
Args[0] = ArgsRes0.get();

ExprResult ArgsRes1 = PerformImplicitConversion(
Args[1], Best->BuiltinParamTypes[1], Best->Conversions[1],
AA_Passing, CCK_ForBuiltinOverloadedOp);
AA_Passing, CheckedConversionKind::ForBuiltinOverloadedOp);
if (ArgsRes1.isInvalid())
return ExprError();
Args[1] = ArgsRes1.get();
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Sema/SemaPseudoObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1136,7 +1136,7 @@ static void CheckKeyForObjCARCConversion(Sema &S, QualType ContainerT,
return;
QualType T = Getter->parameters()[0]->getType();
S.CheckObjCConversion(Key->getSourceRange(), T, Key,
Sema::CCK_ImplicitConversion);
CheckedConversionKind::Implicit);
}

bool ObjCSubscriptOpBuilder::findAtIndexGetter() {
Expand Down
6 changes: 4 additions & 2 deletions clang/lib/Sema/SemaStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaCUDA.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/SemaOpenMP.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
Expand Down Expand Up @@ -3097,7 +3098,7 @@ StmtResult Sema::BuildCXXForRangeStmt(
// In OpenMP loop region loop control variable must be private. Perform
// analysis of first part (if any).
if (getLangOpts().OpenMP >= 50 && BeginDeclStmt.isUsable())
ActOnOpenMPLoopInitialization(ForLoc, BeginDeclStmt.get());
OpenMP().ActOnOpenMPLoopInitialization(ForLoc, BeginDeclStmt.get());

return new (Context) CXXForRangeStmt(
InitStmt, RangeDS, cast_or_null<DeclStmt>(BeginDeclStmt.get()),
Expand Down Expand Up @@ -4822,7 +4823,8 @@ buildCapturedStmtCaptureList(Sema &S, CapturedRegionScopeInfo *RSI,
assert(Cap.isVariableCapture() && "unknown kind of capture");

if (S.getLangOpts().OpenMP && RSI->CapRegionKind == CR_OpenMP)
S.setOpenMPCaptureKind(Field, Cap.getVariable(), RSI->OpenMPLevel);
S.OpenMP().setOpenMPCaptureKind(Field, Cap.getVariable(),
RSI->OpenMPLevel);

Captures.push_back(CapturedStmt::Capture(
Cap.getLocation(),
Expand Down
60 changes: 32 additions & 28 deletions clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaCUDA.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/SemaOpenMP.h"
#include "clang/Sema/Template.h"
#include "clang/Sema/TemplateInstCallback.h"
#include "llvm/Support/TimeProfiler.h"
Expand Down Expand Up @@ -399,7 +400,7 @@ static void instantiateOMPDeclareSimdDeclAttr(
++SI;
}
LinModifiers.append(Attr.modifiers_begin(), Attr.modifiers_end());
(void)S.ActOnOpenMPDeclareSimdDirective(
(void)S.OpenMP().ActOnOpenMPDeclareSimdDirective(
S.ConvertDeclToDeclGroup(New), Attr.getBranchState(), Simdlen.get(),
Uniforms, Aligneds, Alignments, Linears, LinModifiers, Steps,
Attr.getRange());
Expand Down Expand Up @@ -476,9 +477,9 @@ static void instantiateOMPDeclareVariantAttr(
// Check function/variant ref for `omp declare variant` but not for `omp
// begin declare variant` (which use implicit attributes).
std::optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =
S.checkOpenMPDeclareVariantFunction(S.ConvertDeclToDeclGroup(New), E, TI,
Attr.appendArgs_size(),
Attr.getRange());
S.OpenMP().checkOpenMPDeclareVariantFunction(
S.ConvertDeclToDeclGroup(New), E, TI, Attr.appendArgs_size(),
Attr.getRange());

if (!DeclVarData)
return;
Expand Down Expand Up @@ -539,7 +540,7 @@ static void instantiateOMPDeclareVariantAttr(
AppendArgs.emplace_back(II.IsTarget, II.IsTargetSync);
}

S.ActOnOpenMPDeclareVariantDirective(
S.OpenMP().ActOnOpenMPDeclareVariantDirective(
FD, E, TI, NothingExprs, NeedDevicePtrExprs, AppendArgs, SourceLocation(),
SourceLocation(), Attr.getRange());
}
Expand Down Expand Up @@ -3587,7 +3588,7 @@ Decl *TemplateDeclInstantiator::VisitOMPThreadPrivateDecl(
}

OMPThreadPrivateDecl *TD =
SemaRef.CheckOMPThreadPrivateDecl(D->getLocation(), Vars);
SemaRef.OpenMP().CheckOMPThreadPrivateDecl(D->getLocation(), Vars);

TD->setAccess(AS_public);
Owner->addDecl(TD);
Expand All @@ -3610,22 +3611,22 @@ Decl *TemplateDeclInstantiator::VisitOMPAllocateDecl(OMPAllocateDecl *D) {
ExprResult NewE = SemaRef.SubstExpr(AC->getAllocator(), TemplateArgs);
if (!NewE.isUsable())
continue;
IC = SemaRef.ActOnOpenMPAllocatorClause(
IC = SemaRef.OpenMP().ActOnOpenMPAllocatorClause(
NewE.get(), AC->getBeginLoc(), AC->getLParenLoc(), AC->getEndLoc());
} else if (auto *AC = dyn_cast<OMPAlignClause>(C)) {
ExprResult NewE = SemaRef.SubstExpr(AC->getAlignment(), TemplateArgs);
if (!NewE.isUsable())
continue;
IC = SemaRef.ActOnOpenMPAlignClause(NewE.get(), AC->getBeginLoc(),
AC->getLParenLoc(), AC->getEndLoc());
IC = SemaRef.OpenMP().ActOnOpenMPAlignClause(
NewE.get(), AC->getBeginLoc(), AC->getLParenLoc(), AC->getEndLoc());
// If align clause value ends up being invalid, this can end up null.
if (!IC)
continue;
}
Clauses.push_back(IC);
}

Sema::DeclGroupPtrTy Res = SemaRef.ActOnOpenMPAllocateDirective(
Sema::DeclGroupPtrTy Res = SemaRef.OpenMP().ActOnOpenMPAllocateDirective(
D->getLocation(), Vars, Clauses, Owner);
if (Res.get().isNull())
return nullptr;
Expand All @@ -3646,7 +3647,7 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl(
D->getType()->containsUnexpandedParameterPack();
QualType SubstReductionType;
if (RequiresInstantiation) {
SubstReductionType = SemaRef.ActOnOpenMPDeclareReductionType(
SubstReductionType = SemaRef.OpenMP().ActOnOpenMPDeclareReductionType(
D->getLocation(),
ParsedType::make(SemaRef.SubstType(
D->getType(), TemplateArgs, D->getLocation(), DeclarationName())));
Expand All @@ -3667,7 +3668,7 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl(
SemaRef.CurrentInstantiationScope->findInstantiationOf(PrevDeclInScope)
->get<Decl *>());
}
auto DRD = SemaRef.ActOnOpenMPDeclareReductionDirectiveStart(
auto DRD = SemaRef.OpenMP().ActOnOpenMPDeclareReductionDirectiveStart(
/*S=*/nullptr, Owner, D->getDeclName(), ReductionTypes, D->getAccess(),
PrevDeclInScope);
auto *NewDRD = cast<OMPDeclareReductionDecl>(DRD.get().getSingleDecl());
Expand All @@ -3676,7 +3677,7 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl(
Expr *SubstInitializer = nullptr;
// Combiners instantiation sequence.
if (Combiner) {
SemaRef.ActOnOpenMPDeclareReductionCombinerStart(
SemaRef.OpenMP().ActOnOpenMPDeclareReductionCombinerStart(
/*S=*/nullptr, NewDRD);
SemaRef.CurrentInstantiationScope->InstantiatedLocal(
cast<DeclRefExpr>(D->getCombinerIn())->getDecl(),
Expand All @@ -3688,12 +3689,14 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl(
Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, Qualifiers(),
ThisContext);
SubstCombiner = SemaRef.SubstExpr(Combiner, TemplateArgs).get();
SemaRef.ActOnOpenMPDeclareReductionCombinerEnd(NewDRD, SubstCombiner);
SemaRef.OpenMP().ActOnOpenMPDeclareReductionCombinerEnd(NewDRD,
SubstCombiner);
}
// Initializers instantiation sequence.
if (Init) {
VarDecl *OmpPrivParm = SemaRef.ActOnOpenMPDeclareReductionInitializerStart(
/*S=*/nullptr, NewDRD);
VarDecl *OmpPrivParm =
SemaRef.OpenMP().ActOnOpenMPDeclareReductionInitializerStart(
/*S=*/nullptr, NewDRD);
SemaRef.CurrentInstantiationScope->InstantiatedLocal(
cast<DeclRefExpr>(D->getInitOrig())->getDecl(),
cast<DeclRefExpr>(NewDRD->getInitOrig())->getDecl());
Expand All @@ -3710,8 +3713,8 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl(
SemaRef.InstantiateVariableInitializer(OmpPrivParm, OldPrivParm,
TemplateArgs);
}
SemaRef.ActOnOpenMPDeclareReductionInitializerEnd(NewDRD, SubstInitializer,
OmpPrivParm);
SemaRef.OpenMP().ActOnOpenMPDeclareReductionInitializerEnd(
NewDRD, SubstInitializer, OmpPrivParm);
}
IsCorrect = IsCorrect && SubstCombiner &&
(!Init ||
Expand All @@ -3720,7 +3723,7 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl(
(D->getInitializerKind() != OMPDeclareReductionInitKind::Call &&
!SubstInitializer));

(void)SemaRef.ActOnOpenMPDeclareReductionDirectiveEnd(
(void)SemaRef.OpenMP().ActOnOpenMPDeclareReductionDirectiveEnd(
/*S=*/nullptr, DRD, IsCorrect && !D->isInvalidDecl());

return NewDRD;
Expand All @@ -3736,7 +3739,7 @@ TemplateDeclInstantiator::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {
QualType SubstMapperTy;
DeclarationName VN = D->getVarName();
if (RequiresInstantiation) {
SubstMapperTy = SemaRef.ActOnOpenMPDeclareMapperType(
SubstMapperTy = SemaRef.OpenMP().ActOnOpenMPDeclareMapperType(
D->getLocation(),
ParsedType::make(SemaRef.SubstType(D->getType(), TemplateArgs,
D->getLocation(), VN)));
Expand All @@ -3756,11 +3759,12 @@ TemplateDeclInstantiator::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {
SmallVector<OMPClause *, 6> Clauses;
// Instantiate the mapper variable.
DeclarationNameInfo DirName;
SemaRef.StartOpenMPDSABlock(llvm::omp::OMPD_declare_mapper, DirName,
/*S=*/nullptr,
(*D->clauselist_begin())->getBeginLoc());
ExprResult MapperVarRef = SemaRef.ActOnOpenMPDeclareMapperDirectiveVarDecl(
/*S=*/nullptr, SubstMapperTy, D->getLocation(), VN);
SemaRef.OpenMP().StartOpenMPDSABlock(llvm::omp::OMPD_declare_mapper, DirName,
/*S=*/nullptr,
(*D->clauselist_begin())->getBeginLoc());
ExprResult MapperVarRef =
SemaRef.OpenMP().ActOnOpenMPDeclareMapperDirectiveVarDecl(
/*S=*/nullptr, SubstMapperTy, D->getLocation(), VN);
SemaRef.CurrentInstantiationScope->InstantiatedLocal(
cast<DeclRefExpr>(D->getMapperVarRef())->getDecl(),
cast<DeclRefExpr>(MapperVarRef.get())->getDecl());
Expand Down Expand Up @@ -3790,17 +3794,17 @@ TemplateDeclInstantiator::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {
SemaRef.SubstDeclarationNameInfo(OldC->getMapperIdInfo(), TemplateArgs);
OMPVarListLocTy Locs(OldC->getBeginLoc(), OldC->getLParenLoc(),
OldC->getEndLoc());
OMPClause *NewC = SemaRef.ActOnOpenMPMapClause(
OMPClause *NewC = SemaRef.OpenMP().ActOnOpenMPMapClause(
OldC->getIteratorModifier(), OldC->getMapTypeModifiers(),
OldC->getMapTypeModifiersLoc(), SS, NewNameInfo, OldC->getMapType(),
OldC->isImplicitMapType(), OldC->getMapLoc(), OldC->getColonLoc(),
NewVars, Locs);
Clauses.push_back(NewC);
}
SemaRef.EndOpenMPDSABlock(nullptr);
SemaRef.OpenMP().EndOpenMPDSABlock(nullptr);
if (!IsCorrect)
return nullptr;
Sema::DeclGroupPtrTy DG = SemaRef.ActOnOpenMPDeclareMapperDirective(
Sema::DeclGroupPtrTy DG = SemaRef.OpenMP().ActOnOpenMPDeclareMapperDirective(
/*S=*/nullptr, Owner, D->getDeclName(), SubstMapperTy, D->getLocation(),
VN, D->getAccess(), MapperVarRef.get(), Clauses, PrevDeclInScope);
Decl *NewDMD = DG.get().getSingleDecl();
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Sema/SemaType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaCUDA.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/SemaOpenMP.h"
#include "clang/Sema/Template.h"
#include "clang/Sema/TemplateInstCallback.h"
#include "llvm/ADT/ArrayRef.h"
Expand Down Expand Up @@ -2640,7 +2641,7 @@ QualType Sema::BuildArrayType(QualType T, ArraySizeModifier ASM,
} else if (isSFINAEContext()) {
VLADiag = diag::err_vla_in_sfinae;
VLAIsError = true;
} else if (getLangOpts().OpenMP && isInOpenMPTaskUntiedContext()) {
} else if (getLangOpts().OpenMP && OpenMP().isInOpenMPTaskUntiedContext()) {
VLADiag = diag::err_openmp_vla_in_task_untied;
VLAIsError = true;
} else if (getLangOpts().CPlusPlus) {
Expand Down
784 changes: 423 additions & 361 deletions clang/lib/Sema/TreeTransform.h

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions clang/lib/Serialization/ASTReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/ODRDiagsEmitter.h"
#include "clang/AST/ODRHash.h"
#include "clang/AST/OpenACCClause.h"
#include "clang/AST/OpenMPClause.h"
#include "clang/AST/RawCommentList.h"
Expand Down Expand Up @@ -11781,6 +11780,12 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
return OpenACCIfClause::Create(getContext(), BeginLoc, LParenLoc, CondExpr,
EndLoc);
}
case OpenACCClauseKind::Self: {
SourceLocation LParenLoc = readSourceLocation();
Expr *CondExpr = readBool() ? readSubExpr() : nullptr;
return OpenACCSelfClause::Create(getContext(), BeginLoc, LParenLoc,
CondExpr, EndLoc);
}
case OpenACCClauseKind::Finalize:
case OpenACCClauseKind::IfPresent:
case OpenACCClauseKind::Seq:
Expand All @@ -11789,7 +11794,6 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
case OpenACCClauseKind::Worker:
case OpenACCClauseKind::Vector:
case OpenACCClauseKind::NoHost:
case OpenACCClauseKind::Self:
case OpenACCClauseKind::Copy:
case OpenACCClauseKind::UseDevice:
case OpenACCClauseKind::Attach:
Expand Down
9 changes: 8 additions & 1 deletion clang/lib/Serialization/ASTWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7524,6 +7524,14 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
AddStmt(const_cast<Expr *>(IC->getConditionExpr()));
return;
}
case OpenACCClauseKind::Self: {
const auto *SC = cast<OpenACCIfClause>(C);
writeSourceLocation(SC->getLParenLoc());
writeBool(SC->hasConditionExpr());
if (SC->hasConditionExpr())
AddStmt(const_cast<Expr *>(SC->getConditionExpr()));
return;
}
case OpenACCClauseKind::Finalize:
case OpenACCClauseKind::IfPresent:
case OpenACCClauseKind::Seq:
Expand All @@ -7532,7 +7540,6 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
case OpenACCClauseKind::Worker:
case OpenACCClauseKind::Vector:
case OpenACCClauseKind::NoHost:
case OpenACCClauseKind::Self:
case OpenACCClauseKind::Copy:
case OpenACCClauseKind::UseDevice:
case OpenACCClauseKind::Attach:
Expand Down
1 change: 0 additions & 1 deletion clang/lib/Serialization/ASTWriterDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ODRHash.h"
#include "clang/AST/OpenMPClause.h"
#include "clang/AST/PrettyDeclStackTrace.h"
#include "clang/Basic/SourceManager.h"
Expand Down
1 change: 0 additions & 1 deletion clang/lib/Serialization/ASTWriterStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#include "clang/AST/ExprOpenMP.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Lex/Token.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Serialization/ASTRecordWriter.h"
#include "llvm/Bitstream/BitstreamWriter.h"
using namespace clang;
Expand Down
1 change: 0 additions & 1 deletion clang/lib/Serialization/GeneratePCH.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/SemaConsumer.h"
#include "clang/Serialization/ASTReader.h"
#include "clang/Serialization/ASTWriter.h"
#include "llvm/Bitstream/BitstreamWriter.h"

Expand Down
1 change: 0 additions & 1 deletion clang/lib/Serialization/GlobalModuleIndex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include "clang/Serialization/GlobalModuleIndex.h"
#include "ASTReaderInternals.h"
#include "clang/Basic/FileManager.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Serialization/ASTBitCodes.h"
#include "clang/Serialization/ModuleFile.h"
#include "clang/Serialization/PCHContainerOperations.h"
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Serialization/ModuleFileExtension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
#include "clang/Serialization/ModuleFileExtension.h"
#include "llvm/ADT/Hashing.h"

using namespace clang;

char ModuleFileExtension::ID = 0;
Expand Down
2 changes: 0 additions & 2 deletions clang/lib/Serialization/PCHContainerOperations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@

#include "clang/Serialization/PCHContainerOperations.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/Lex/ModuleLoader.h"
#include "llvm/Bitstream/BitstreamReader.h"
#include "llvm/Support/raw_ostream.h"
#include <utility>

Expand Down
31 changes: 20 additions & 11 deletions clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,28 +48,33 @@ class InvalidPtrChecker
bool InvalidatingGetEnv = false;

// GetEnv can be treated invalidating and non-invalidating as well.
const CallDescription GetEnvCall{{"getenv"}, 1};
const CallDescription GetEnvCall{CDM::CLibrary, {"getenv"}, 1};

const CallDescriptionMap<HandlerFn> EnvpInvalidatingFunctions = {
{{{"setenv"}, 3}, &InvalidPtrChecker::EnvpInvalidatingCall},
{{{"unsetenv"}, 1}, &InvalidPtrChecker::EnvpInvalidatingCall},
{{{"putenv"}, 1}, &InvalidPtrChecker::EnvpInvalidatingCall},
{{{"_putenv_s"}, 2}, &InvalidPtrChecker::EnvpInvalidatingCall},
{{{"_wputenv_s"}, 2}, &InvalidPtrChecker::EnvpInvalidatingCall},
{{CDM::CLibrary, {"setenv"}, 3},
&InvalidPtrChecker::EnvpInvalidatingCall},
{{CDM::CLibrary, {"unsetenv"}, 1},
&InvalidPtrChecker::EnvpInvalidatingCall},
{{CDM::CLibrary, {"putenv"}, 1},
&InvalidPtrChecker::EnvpInvalidatingCall},
{{CDM::CLibrary, {"_putenv_s"}, 2},
&InvalidPtrChecker::EnvpInvalidatingCall},
{{CDM::CLibrary, {"_wputenv_s"}, 2},
&InvalidPtrChecker::EnvpInvalidatingCall},
};

void postPreviousReturnInvalidatingCall(const CallEvent &Call,
CheckerContext &C) const;

// SEI CERT ENV34-C
const CallDescriptionMap<HandlerFn> PreviousCallInvalidatingFunctions = {
{{{"setlocale"}, 2},
{{CDM::CLibrary, {"setlocale"}, 2},
&InvalidPtrChecker::postPreviousReturnInvalidatingCall},
{{{"strerror"}, 1},
{{CDM::CLibrary, {"strerror"}, 1},
&InvalidPtrChecker::postPreviousReturnInvalidatingCall},
{{{"localeconv"}, 0},
{{CDM::CLibrary, {"localeconv"}, 0},
&InvalidPtrChecker::postPreviousReturnInvalidatingCall},
{{{"asctime"}, 1},
{{CDM::CLibrary, {"asctime"}, 1},
&InvalidPtrChecker::postPreviousReturnInvalidatingCall},
};

Expand Down Expand Up @@ -205,8 +210,12 @@ void InvalidPtrChecker::postPreviousReturnInvalidatingCall(
CE, LCtx, CE->getType(), C.blockCount());
State = State->BindExpr(CE, LCtx, RetVal);

const auto *SymRegOfRetVal =
dyn_cast_or_null<SymbolicRegion>(RetVal.getAsRegion());
if (!SymRegOfRetVal)
return;

// Remember to this region.
const auto *SymRegOfRetVal = cast<SymbolicRegion>(RetVal.getAsRegion());
const MemRegion *MR = SymRegOfRetVal->getBaseRegion();
State = State->set<PreviousCallResultMap>(FD, MR);

Expand Down
17 changes: 15 additions & 2 deletions clang/test/AST/Interp/vectors.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both %s
// RUN: %clang_cc1 -verify=ref,both %s

// ref-no-diagnostics

typedef int __attribute__((vector_size(16))) VI4;
constexpr VI4 A = {1,2,3,4};
static_assert(A[0] == 1, ""); // ref-error {{not an integral constant expression}}
static_assert(A[1] == 2, ""); // ref-error {{not an integral constant expression}}
static_assert(A[2] == 3, ""); // ref-error {{not an integral constant expression}}
static_assert(A[3] == 4, ""); // ref-error {{not an integral constant expression}}

/// VectorSplat casts
typedef __attribute__(( ext_vector_type(4) )) float float4;
constexpr float4 vec4_0 = (float4)0.5f;
static_assert(vec4_0[0] == 0.5, ""); // ref-error {{not an integral constant expression}}
static_assert(vec4_0[1] == 0.5, ""); // ref-error {{not an integral constant expression}}
static_assert(vec4_0[2] == 0.5, ""); // ref-error {{not an integral constant expression}}
static_assert(vec4_0[3] == 0.5, ""); // ref-error {{not an integral constant expression}}
constexpr int vec4_0_discarded = ((float4)12.0f, 0);



/// From constant-expression-cxx11.cpp
namespace Vector {
Expand Down
10 changes: 10 additions & 0 deletions clang/test/Analysis/invalid-ptr-checker.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// RUN: %clang_analyze_cc1 -analyzer-checker=core,security.cert.env.InvalidPtr -verify %s

// expected-no-diagnostics

namespace other {
int strerror(int errnum); // custom strerror
void no_crash_on_custom_strerror() {
(void)strerror(0); // no-crash
}
} // namespace other
14 changes: 9 additions & 5 deletions clang/test/CXX/drs/dr0xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx11,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors -triple %itanium_abi_triple
// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx11,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors -triple %itanium_abi_triple

#if __cplusplus == 199711L
#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
// cxx98-error@-1 {{variadic macros are a C99 feature}}
#endif

namespace cwg1 { // cwg1: no
namespace X { extern "C" void cwg1_f(int a = 1); }
namespace Y { extern "C" void cwg1_f(int a = 1); }
Expand Down Expand Up @@ -897,7 +902,7 @@ namespace cwg54 { // cwg54: 2.8

namespace cwg55 { // cwg55: yes
enum E { e = 5 };
int test[(e + 1 == 6) ? 1 : -1];
static_assert(e + 1 == 6, "");
}

namespace cwg56 { // cwg56: yes
Expand Down Expand Up @@ -1163,10 +1168,9 @@ namespace cwg75 { // cwg75: yes

namespace cwg76 { // cwg76: yes
const volatile int n = 1;
int arr[n]; // #cwg76-vla
// expected-error@#cwg76-vla {{variable length arrays in C++ are a Clang extension}}
// expected-note@#cwg76-vla {{read of volatile-qualified type 'const volatile int' is not allowed in a constant expression}}
// expected-error@#cwg76-vla {{variable length array declaration not allowed at file scope}}
static_assert(n, "");
// expected-error@-1 {{static assertion expression is not an integral constant expression}}
// expected-note@-2 {{read of volatile-qualified type 'const volatile int' is not allowed in a constant expression}}
}

namespace cwg77 { // cwg77: yes
Expand Down
5 changes: 2 additions & 3 deletions clang/test/CXX/drs/dr16xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,9 @@ namespace cwg1645 { // cwg1645: 3.9

namespace cwg1652 { // cwg1652: 3.6
int a, b;
int arr[&a + 1 == &b ? 1 : 2];
// expected-error@-1 {{variable length arrays in C++ are a Clang extension}}
static_assert(&a + 1 == &b, "");
// expected-error@-1 {{static assertion expression is not an integral constant expression}}
// expected-note@-2 {{comparison against pointer '&a + 1' that points past the end of a complete object has unspecified value}}
// expected-error@-3 {{variable length array declaration not allowed at file scope}}
}

namespace cwg1653 { // cwg1653: 4 c++17
Expand Down
61 changes: 33 additions & 28 deletions clang/test/CXX/drs/dr1xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors

#if __cplusplus == 199711L
#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
// cxx98-error@-1 {{variadic macros are a C99 feature}}
#endif

#if __cplusplus == 199711L
#define __enable_constant_folding(x) (__builtin_constant_p(x) ? (x) : (x))
#else
#define __enable_constant_folding
#endif

namespace cwg100 { // cwg100: yes
template<const char (*)[4]> struct A {}; // #cwg100-A
template<const char (&)[4]> struct B {}; // #cwg100-B
Expand Down Expand Up @@ -736,22 +747,16 @@ namespace cwg147 { // cwg147: yes

namespace cwg148 { // cwg148: yes
struct A { int A::*p; };
int check1[__is_pod(int(A::*)) ? 1 : -1];
int check2[__is_pod(A) ? 1 : -1];
static_assert(__is_pod(int(A::*)), "");
static_assert(__is_pod(A), "");
}

// cwg149: na

namespace cwg151 { // cwg151: 3.1
struct X {};
typedef int X::*p;
#if __cplusplus < 201103L
#define fold(x) (__builtin_constant_p(0) ? (x) : (x))
#else
#define fold
#endif
int check[fold(p() == 0) ? 1 : -1];
#undef fold
static_assert(__enable_constant_folding(p() == 0), "");
}

namespace cwg152 { // cwg152: yes
Expand Down Expand Up @@ -956,42 +961,42 @@ namespace cwg171 {

namespace cwg172 { // cwg172: yes
enum { zero };
int check1[-1 < zero ? 1 : -1];
static_assert(-1 < zero, "");

enum { x = -1, y = (unsigned int)-1 };
int check2[sizeof(x) > sizeof(int) ? 1 : -1];
static_assert(sizeof(x) > sizeof(int), "");

enum { a = (unsigned int)-1 / 2 };
int check3a[sizeof(a) == sizeof(int) ? 1 : -1];
int check3b[-a < 0 ? 1 : -1];
static_assert(sizeof(a) == sizeof(int), "");
static_assert(-a < 0, "");

enum { b = (unsigned int)-1 / 2 + 1 };
int check4a[sizeof(b) == sizeof(unsigned int) ? 1 : -1];
int check4b[-b > 0 ? 1 : -1];
static_assert(sizeof(b) == sizeof(unsigned int), "");
static_assert(-b > 0, "");

enum { c = (unsigned long)-1 / 2 };
int check5a[sizeof(c) == sizeof(long) ? 1 : -1];
int check5b[-c < 0 ? 1 : -1];
static_assert(sizeof(c) == sizeof(long), "");
static_assert(-c < 0, "");

enum { d = (unsigned long)-1 / 2 + 1 };
int check6a[sizeof(d) == sizeof(unsigned long) ? 1 : -1];
int check6b[-d > 0 ? 1 : -1];
static_assert(sizeof(d) == sizeof(unsigned long), "");
static_assert(-d > 0, "");

enum { e = (unsigned long long)-1 / 2 };
// cxx98-error@-1 {{'long long' is a C++11 extension}}
int check7a[sizeof(e) == sizeof(long) ? 1 : -1];
int check7b[-e < 0 ? 1 : -1];
static_assert(sizeof(e) == sizeof(long), "");
static_assert(-e < 0, "");

enum { f = (unsigned long long)-1 / 2 + 1 };
// cxx98-error@-1 {{'long long' is a C++11 extension}}
int check8a[sizeof(f) == sizeof(unsigned long) ? 1 : -1];
int check8b[-f > 0 ? 1 : -1];
static_assert(sizeof(f) == sizeof(unsigned long), "");
static_assert(-f > 0, "");
}

namespace cwg173 { // cwg173: yes
int check[('0' + 1 == '1' && '0' + 2 == '2' && '0' + 3 == '3' &&
'0' + 4 == '4' && '0' + 5 == '5' && '0' + 6 == '6' &&
'0' + 7 == '7' && '0' + 8 == '8' && '0' + 9 == '9') ? 1 : -1];
static_assert('0' + 1 == '1' && '0' + 2 == '2' && '0' + 3 == '3' &&
'0' + 4 == '4' && '0' + 5 == '5' && '0' + 6 == '6' &&
'0' + 7 == '7' && '0' + 8 == '8' && '0' + 9 == '9', "");
}

// cwg174: sup 1012
Expand Down Expand Up @@ -1070,7 +1075,7 @@ namespace cwg177 { // cwg177: yes
}

namespace cwg178 { // cwg178: yes
int check[int() == 0 ? 1 : -1];
static_assert(int() == 0, "");
#if __cplusplus >= 201103L
static_assert(int{} == 0, "");
struct S { int a, b; };
Expand Down Expand Up @@ -1180,7 +1185,7 @@ namespace cwg187 { // cwg187: sup 481

namespace cwg188 { // cwg188: yes
char c[10];
int check[sizeof(0, c) == 10 ? 1 : -1];
static_assert(sizeof(0, c) == 10, "");
}

// cwg190 FIXME: add codegen test for tbaa
Expand Down
15 changes: 10 additions & 5 deletions clang/test/CXX/drs/dr2xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@
typedef __SIZE_TYPE__ size_t;
// cxx98-error@-1 0-1 {{'long long' is a C++11 extension}}

#if __cplusplus < 201103L
#define fold(x) (__builtin_constant_p(x) ? (x) : (x))
#if __cplusplus == 199711L
#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
// cxx98-error@-1 {{variadic macros are a C99 feature}}
#endif

#if __cplusplus == 199711L
#define __enable_constant_folding(x) (__builtin_constant_p(x) ? (x) : (x))
#else
#define fold
#define __enable_constant_folding
#endif

namespace cwg200 { // cwg200: dup 214
Expand All @@ -31,7 +36,7 @@ namespace cwg200 { // cwg200: dup 214
namespace cwg202 { // cwg202: 3.1
template<typename T> T f();
template<int (*g)()> struct X {
int arr[fold(g == &f<int>) ? 1 : -1];
static_assert(__enable_constant_folding(g == &f<int>), "");
};
template struct X<f>;
}
Expand Down Expand Up @@ -1024,7 +1029,7 @@ namespace cwg275 { // cwg275: no
namespace cwg277 { // cwg277: 3.1
typedef int *intp;
int *p = intp();
int a[fold(intp() ? -1 : 1)];
static_assert(__enable_constant_folding(!intp()), "");
}

namespace cwg280 { // cwg280: 2.9
Expand Down
Loading