Skip to content

Commit

Permalink
Merged main:b3fbb67379a4 into amd-gfx:6fa5d2831ccc
Browse files Browse the repository at this point in the history
Local branch amd-gfx 6fa5d28 Merged main:6ade5183232d into amd-gfx:d5105ae3c5a9
Remote branch main b3fbb67 [mlir][sparse] cleanup of COO (llvm#69239)
  • Loading branch information
SC llvm team authored and SC llvm team committed Oct 16, 2023
2 parents 6fa5d28 + b3fbb67 commit 8892e09
Show file tree
Hide file tree
Showing 66 changed files with 1,161 additions and 947 deletions.
7 changes: 7 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,11 @@ Bug Fixes to C++ Support
rather than prefer the non-templated constructor as specified in
[standard.group]p3.

- Fix a bug where implicit deduction guides are not correctly generated for nested template
classes. Fixes:
(`#46200 <https://github.com/llvm/llvm-project/issues/46200>`_)
(`#57812 <https://github.com/llvm/llvm-project/issues/57812>`_)

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
- Fixed an import failure of recursive friend class template.
Expand All @@ -521,6 +526,8 @@ Bug Fixes to AST Handling
computed RecordLayout is incorrect if fields are not completely imported and
should not be cached.
`Issue 64170 <https://github.com/llvm/llvm-project/issues/64170>`_
- Fixed ``hasAnyBase`` not binding nodes in its submatcher.
(`#65421 <https://github.com/llvm/llvm-project/issues/65421>`_)

Miscellaneous Bug Fixes
^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/ASTMatchers/ASTMatchersInternal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ bool matchesAnyBase(const CXXRecordDecl &Node,
[Finder, Builder, &BaseSpecMatcher](const CXXBaseSpecifier *BaseSpec,
CXXBasePath &IgnoredParam) {
BoundNodesTreeBuilder Result(*Builder);
if (BaseSpecMatcher.matches(*BaseSpec, Finder, Builder)) {
if (BaseSpecMatcher.matches(*BaseSpec, Finder, &Result)) {
*Builder = std::move(Result);
return true;
}
Expand Down
35 changes: 15 additions & 20 deletions clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//

#include <algorithm>
#include <memory>
#include <optional>
#include <system_error>
#include <utility>
Expand All @@ -33,8 +32,8 @@
#include "clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h"
#include "clang/Analysis/FlowSensitive/Value.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Error.h"

Expand All @@ -53,19 +52,14 @@ static int blockIndexInPredecessor(const CFGBlock &Pred,
return BlockPos - Pred.succ_begin();
}

static bool isLoopHead(const CFGBlock &B) {
if (const auto *T = B.getTerminatorStmt())
switch (T->getStmtClass()) {
case Stmt::WhileStmtClass:
case Stmt::DoStmtClass:
case Stmt::ForStmtClass:
case Stmt::CXXForRangeStmtClass:
return true;
default:
return false;
}

return false;
// A "backedge" node is a block introduced in the CFG exclusively to indicate a
// loop backedge. They are exactly identified by the presence of a non-null
// pointer to the entry block of the loop condition. Note that this is not
// necessarily the block with the loop statement as terminator, because
// short-circuit operators will result in multiple blocks encoding the loop
// condition, only one of which will contain the loop statement as terminator.
static bool isBackedgeNode(const CFGBlock &B) {
return B.getLoopTarget() != nullptr;
}

namespace {
Expand Down Expand Up @@ -502,14 +496,15 @@ runTypeErasedDataflowAnalysis(
PostVisitCFG) {
PrettyStackTraceAnalysis CrashInfo(CFCtx, "runTypeErasedDataflowAnalysis");

PostOrderCFGView POV(&CFCtx.getCFG());
ForwardDataflowWorklist Worklist(CFCtx.getCFG(), &POV);
const clang::CFG &CFG = CFCtx.getCFG();
PostOrderCFGView POV(&CFG);
ForwardDataflowWorklist Worklist(CFG, &POV);

std::vector<std::optional<TypeErasedDataflowAnalysisState>> BlockStates(
CFCtx.getCFG().size());
CFG.size());

// The entry basic block doesn't contain statements so it can be skipped.
const CFGBlock &Entry = CFCtx.getCFG().getEntry();
const CFGBlock &Entry = CFG.getEntry();
BlockStates[Entry.getBlockID()] = {Analysis.typeErasedInitialElement(),
InitEnv.fork()};
Worklist.enqueueSuccessors(&Entry);
Expand Down Expand Up @@ -553,7 +548,7 @@ runTypeErasedDataflowAnalysis(
llvm::errs() << "Old Env:\n";
OldBlockState->Env.dump();
});
if (isLoopHead(*Block)) {
if (isBackedgeNode(*Block)) {
LatticeJoinEffect Effect1 = Analysis.widenTypeErased(
NewBlockState.Lattice, OldBlockState->Lattice);
LatticeJoinEffect Effect2 =
Expand Down
37 changes: 7 additions & 30 deletions clang/lib/Sema/SemaInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/ExprOpenMP.h"
#include "clang/AST/IgnoreExpr.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/SourceManager.h"
Expand Down Expand Up @@ -170,22 +171,9 @@ static void updateStringLiteralType(Expr *E, QualType Ty) {
while (true) {
E->setType(Ty);
E->setValueKind(VK_PRValue);
if (isa<StringLiteral>(E) || isa<ObjCEncodeExpr>(E)) {
break;
} else if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
E = PE->getSubExpr();
} else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
assert(UO->getOpcode() == UO_Extension);
E = UO->getSubExpr();
} else if (GenericSelectionExpr *GSE = dyn_cast<GenericSelectionExpr>(E)) {
E = GSE->getResultExpr();
} else if (ChooseExpr *CE = dyn_cast<ChooseExpr>(E)) {
E = CE->getChosenSubExpr();
} else if (PredefinedExpr *PE = dyn_cast<PredefinedExpr>(E)) {
E = PE->getFunctionName();
} else {
llvm_unreachable("unexpected expr in string literal init");
}
if (isa<StringLiteral>(E) || isa<ObjCEncodeExpr>(E))
break;
E = IgnoreParensSingleStep(E);
}
}

Expand All @@ -194,20 +182,9 @@ static void updateStringLiteralType(Expr *E, QualType Ty) {
static void updateGNUCompoundLiteralRValue(Expr *E) {
while (true) {
E->setValueKind(VK_PRValue);
if (isa<CompoundLiteralExpr>(E)) {
break;
} else if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
E = PE->getSubExpr();
} else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
assert(UO->getOpcode() == UO_Extension);
E = UO->getSubExpr();
} else if (GenericSelectionExpr *GSE = dyn_cast<GenericSelectionExpr>(E)) {
E = GSE->getResultExpr();
} else if (ChooseExpr *CE = dyn_cast<ChooseExpr>(E)) {
E = CE->getChosenSubExpr();
} else {
llvm_unreachable("unexpected expr in array compound literal init");
}
if (isa<CompoundLiteralExpr>(E))
break;
E = IgnoreParensSingleStep(E);
}
}

Expand Down
22 changes: 21 additions & 1 deletion clang/lib/Sema/SemaTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2250,6 +2250,7 @@ struct ConvertConstructorToDeductionGuideTransform {

Sema &SemaRef;
ClassTemplateDecl *Template;
ClassTemplateDecl *NestedPattern = nullptr;

DeclContext *DC = Template->getDeclContext();
CXXRecordDecl *Primary = Template->getTemplatedDecl();
Expand Down Expand Up @@ -2327,6 +2328,8 @@ struct ConvertConstructorToDeductionGuideTransform {
if (FTD) {
Args.addOuterTemplateArguments(SubstArgs);
Args.addOuterRetainedLevel();
if (NestedPattern)
Args.addOuterRetainedLevels(NestedPattern->getTemplateDepth());
}

FunctionProtoTypeLoc FPTL = CD->getTypeSourceInfo()->getTypeLoc()
Expand Down Expand Up @@ -2438,10 +2441,17 @@ struct ConvertConstructorToDeductionGuideTransform {
SmallVector<QualType, 4> ParamTypes;
const FunctionProtoType *T = TL.getTypePtr();

MultiLevelTemplateArgumentList OuterInstantiationArgs;
if (NestedPattern)
OuterInstantiationArgs = SemaRef.getTemplateInstantiationArgs(Template);

// -- The types of the function parameters are those of the constructor.
for (auto *OldParam : TL.getParams()) {
ParmVarDecl *NewParam =
transformFunctionTypeParam(OldParam, Args, MaterializedTypedefs);
if (NestedPattern && NewParam)
NewParam = transformFunctionTypeParam(NewParam, OuterInstantiationArgs,
MaterializedTypedefs);
if (!NewParam)
return QualType();
ParamTypes.push_back(NewParam->getType());
Expand Down Expand Up @@ -2647,13 +2657,23 @@ void Sema::DeclareImplicitDeductionGuides(TemplateDecl *Template,
if (BuildingDeductionGuides.isInvalid())
return;

// If the template is nested, then we need to use the original
// pattern to iterate over the constructors.
ClassTemplateDecl *Pattern = Transform.Template;
while (Pattern->getInstantiatedFromMemberTemplate()) {
if (Pattern->isMemberSpecialization())
break;
Pattern = Pattern->getInstantiatedFromMemberTemplate();
Transform.NestedPattern = Pattern;
}

// Convert declared constructors into deduction guide templates.
// FIXME: Skip constructors for which deduction must necessarily fail (those
// for which some class template parameter without a default argument never
// appears in a deduced context).
llvm::SmallPtrSet<NamedDecl *, 8> ProcessedCtors;
bool AddedAny = false;
for (NamedDecl *D : LookupConstructors(Transform.Primary)) {
for (NamedDecl *D : LookupConstructors(Pattern->getTemplatedDecl())) {
D = D->getUnderlyingDecl();
if (D->isInvalidDecl() || D->isImplicit())
continue;
Expand Down
12 changes: 12 additions & 0 deletions clang/test/SemaTemplate/nested-implicit-deduction-guides.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// RUN: %clang_cc1 -std=c++17 -verify %s
// expected-no-diagnostics

template<class T> struct S {
template<class U> struct N {
N(T) {}
N(T, U) {}
template<class V> N(V, U) {}
};
};

S<int>::N x{"a", 1};
13 changes: 13 additions & 0 deletions clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "ASTMatchersTest.h"
#include "clang/AST/Attrs.inc"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
Expand Down Expand Up @@ -5457,6 +5458,18 @@ TEST(HasParent, NoDuplicateParents) {
stmt().bind("node"), std::make_unique<HasDuplicateParents>()));
}

TEST(HasAnyBase, BindsInnerBoundNodes) {
EXPECT_TRUE(matchAndVerifyResultTrue(
"struct Inner {}; struct Proxy : Inner {}; struct Main : public "
"Proxy {};",
cxxRecordDecl(hasName("Main"),
hasAnyBase(cxxBaseSpecifier(hasType(
cxxRecordDecl(hasName("Inner")).bind("base-class")))))
.bind("class"),
std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("base-class",
"Inner")));
}

TEST(TypeMatching, PointeeTypes) {
EXPECT_TRUE(matches("int b; int &a = b;",
referenceType(pointee(builtinType()))));
Expand Down
14 changes: 14 additions & 0 deletions clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4099,6 +4099,20 @@ TEST(TransferTest, LoopDereferencingChangingRecordPointerConverges) {
ASSERT_THAT_ERROR(checkDataflowWithNoopAnalysis(Code), llvm::Succeeded());
}

TEST(TransferTest, LoopWithShortCircuitedConditionConverges) {
std::string Code = R"cc(
bool foo();

void target() {
bool c = false;
while (foo() || foo()) {
c = true;
}
}
)cc";
ASSERT_THAT_ERROR(checkDataflowWithNoopAnalysis(Code), llvm::Succeeded());
}

TEST(TransferTest, DoesNotCrashOnUnionThisExpr) {
std::string Code = R"(
union Union {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,29 @@ TEST_F(FlowConditionTest, WhileStmt) {
});
}

TEST_F(FlowConditionTest, WhileStmtWithAssignmentInCondition) {
std::string Code = R"(
void target(bool Foo) {
// This test checks whether the analysis preserves the connection between
// the value of `Foo` and the assignment expression, despite widening.
// The equality operator generates a fresh boolean variable on each
// interpretation, which forces use of widening.
while ((Foo = (3 == 4))) {
(void)0;
/*[[p]]*/
}
}
)";
runDataflow(
Code,
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
ASTContext &ASTCtx) {
const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
auto &FooVal = getValueForDecl<BoolValue>(ASTCtx, Env, "Foo").formula();
EXPECT_TRUE(Env.flowConditionImplies(FooVal));
});
}

TEST_F(FlowConditionTest, Conjunction) {
std::string Code = R"(
void target(bool Foo, bool Bar) {
Expand Down
4 changes: 2 additions & 2 deletions flang/lib/Lower/Allocatable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ class AllocateStmtHelper {
errorManager.genStatCheck(builder, loc);
genAllocateObjectInit(box);
if (alloc.hasCoarraySpec())
TODO(loc, "coarray allocation");
TODO(loc, "coarray: allocation of a coarray object");
if (alloc.type.IsPolymorphic())
genSetType(alloc, box, loc);
genSetDeferredLengthParameters(alloc, box);
Expand Down Expand Up @@ -582,7 +582,7 @@ class AllocateStmtHelper {
errorManager.genStatCheck(builder, loc);
genAllocateObjectInit(box);
if (alloc.hasCoarraySpec())
TODO(loc, "coarray allocation");
TODO(loc, "coarray: allocation of a coarray object");
// Set length of the allocate object if it has. Otherwise, get the length
// from source for the deferred length parameter.
if (lenParams.empty() && box.isCharacter() &&
Expand Down
18 changes: 9 additions & 9 deletions flang/lib/Lower/Bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2625,35 +2625,35 @@ class FirConverter : public Fortran::lower::AbstractConverter {
}

void genFIR(const Fortran::parser::ChangeTeamConstruct &construct) {
TODO(toLocation(), "ChangeTeamConstruct implementation");
TODO(toLocation(), "coarray: ChangeTeamConstruct");
}
void genFIR(const Fortran::parser::ChangeTeamStmt &stmt) {
TODO(toLocation(), "ChangeTeamStmt implementation");
TODO(toLocation(), "coarray: ChangeTeamStmt");
}
void genFIR(const Fortran::parser::EndChangeTeamStmt &stmt) {
TODO(toLocation(), "EndChangeTeamStmt implementation");
TODO(toLocation(), "coarray: EndChangeTeamStmt");
}

void genFIR(const Fortran::parser::CriticalConstruct &criticalConstruct) {
setCurrentPositionAt(criticalConstruct);
TODO(toLocation(), "CriticalConstruct implementation");
TODO(toLocation(), "coarray: CriticalConstruct");
}
void genFIR(const Fortran::parser::CriticalStmt &) {
TODO(toLocation(), "CriticalStmt implementation");
TODO(toLocation(), "coarray: CriticalStmt");
}
void genFIR(const Fortran::parser::EndCriticalStmt &) {
TODO(toLocation(), "EndCriticalStmt implementation");
TODO(toLocation(), "coarray: EndCriticalStmt");
}

void genFIR(const Fortran::parser::SelectRankConstruct &selectRankConstruct) {
setCurrentPositionAt(selectRankConstruct);
TODO(toLocation(), "SelectRankConstruct implementation");
TODO(toLocation(), "coarray: SelectRankConstruct");
}
void genFIR(const Fortran::parser::SelectRankStmt &) {
TODO(toLocation(), "SelectRankStmt implementation");
TODO(toLocation(), "coarray: SelectRankStmt");
}
void genFIR(const Fortran::parser::SelectRankCaseStmt &) {
TODO(toLocation(), "SelectRankCaseStmt implementation");
TODO(toLocation(), "coarray: SelectRankCaseStmt");
}

void genFIR(const Fortran::parser::SelectTypeConstruct &selectTypeConstruct) {
Expand Down
2 changes: 1 addition & 1 deletion flang/lib/Lower/CallInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -952,7 +952,7 @@ class Fortran::lower::CallInterfaceImpl {
if (shapeAttrs.test(ShapeAttr::AssumedRank))
TODO(loc, "assumed rank in procedure interface");
if (shapeAttrs.test(ShapeAttr::Coarray))
TODO(loc, "coarray in procedure interface");
TODO(loc, "coarray: dummy argument coarray in procedure interface");

// So far assume that if the argument cannot be passed by implicit interface
// it must be by box. That may no be always true (e.g for simple optionals)
Expand Down
Loading

0 comments on commit 8892e09

Please sign in to comment.