Skip to content

[SYCL] Don't diagnose checks in a discarded statement. #3714

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clang/include/clang/AST/Stmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -2080,6 +2080,7 @@ class IfStmt final
/// If this is an 'if constexpr', determine which substatement will be taken.
/// Otherwise, or if the condition is value-dependent, returns None.
Optional<const Stmt*> getNondiscardedCase(const ASTContext &Ctx) const;
Optional<Stmt *> getNondiscardedCase(const ASTContext &Ctx);

bool isObjCAvailabilityCheck() const;

Expand Down
19 changes: 18 additions & 1 deletion clang/include/clang/Analysis/CallGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

namespace clang {

class ASTContext;
class CallGraphNode;
class Decl;
class DeclContext;
Expand All @@ -51,6 +52,12 @@ class CallGraph : public RecursiveASTVisitor<CallGraph> {
/// This is a virtual root node that has edges to all the functions.
CallGraphNode *Root;

/// A setting to determine whether this should include calls that are done in
/// a constant expression's context. This DOES require the ASTContext object
/// for constexpr-if, so setting it requires a valid ASTContext.
bool shouldSkipConstexpr = false;
ASTContext *Ctx;

public:
CallGraph();
~CallGraph();
Expand All @@ -66,7 +73,7 @@ class CallGraph : public RecursiveASTVisitor<CallGraph> {
/// Determine if a declaration should be included in the graph.
static bool includeInGraph(const Decl *D);

/// Determine if a declaration should be included in the graph for the
/// Determine if a declaration should be included in the graph for the
/// purposes of being a callee. This is similar to includeInGraph except
/// it permits declarations, not just definitions.
static bool includeCalleeInGraph(const Decl *D);
Expand Down Expand Up @@ -138,6 +145,16 @@ class CallGraph : public RecursiveASTVisitor<CallGraph> {
bool shouldWalkTypesOfTypeLocs() const { return false; }
bool shouldVisitTemplateInstantiations() const { return true; }
bool shouldVisitImplicitCode() const { return true; }
bool shouldVisitConstantExpressions() const { return false; }
bool shouldSkipConstantExpressions() const { return shouldSkipConstexpr; }
void setSkipConstantExpressions(ASTContext &Context) {
Ctx = &Context;
shouldSkipConstexpr = true;
}
ASTContext &getASTContext() {
assert(Ctx);
return *Ctx;
}

private:
/// Add the given declaration to the call graph.
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/AST/Stmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -995,6 +995,12 @@ Optional<const Stmt*> IfStmt::getNondiscardedCase(const ASTContext &Ctx) const {
return !getCond()->EvaluateKnownConstInt(Ctx) ? getElse() : getThen();
}

Optional<Stmt *> IfStmt::getNondiscardedCase(const ASTContext &Ctx) {
if (!isConstexpr() || getCond()->isValueDependent())
return None;
return !getCond()->EvaluateKnownConstInt(Ctx) ? getElse() : getThen();
}

ForStmt::ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP,
SourceLocation RP)
Expand Down
32 changes: 32 additions & 0 deletions clang/lib/Analysis/CallGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//

#include "clang/Analysis/CallGraph.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclObjC.h"
Expand Down Expand Up @@ -136,6 +137,37 @@ class CGBuilder : public StmtVisitor<CGBuilder> {
}
}

void VisitIfStmt(IfStmt *If) {
if (G->shouldSkipConstantExpressions()) {
if (llvm::Optional<Stmt *> ActiveStmt =
If->getNondiscardedCase(G->getASTContext())) {
if (*ActiveStmt)
this->Visit(*ActiveStmt);
return;
}
}

StmtVisitor::VisitIfStmt(If);
}

void VisitDeclStmt(DeclStmt *DS) {
if (G->shouldSkipConstantExpressions()) {
auto IsConstexprVarDecl = [](Decl *D) {
if (const auto *VD = dyn_cast<VarDecl>(D))
return VD->isConstexpr();
return false;
};
if (llvm::any_of(DS->decls(), IsConstexprVarDecl)) {
assert(llvm::all_of(DS->decls(), IsConstexprVarDecl) &&
"Situation where a decl-group would be a mix of decl types, or "
"constexpr and not?");
return;
}
}

StmtVisitor::VisitDeclStmt(DS);
}

void VisitChildren(Stmt *S) {
for (Stmt *SubStmt : S->children())
if (SubStmt)
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Sema/SemaSYCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ class DeviceFunctionTracker {

public:
DeviceFunctionTracker(Sema &S) : SemaRef(S) {
CG.setSkipConstantExpressions(S.Context);
CG.addToCallGraph(S.getASTContext().getTranslationUnitDecl());
CollectSyclExternalFuncs();
}
Expand Down