Skip to content
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

Fix for issue 5 #6

Merged
merged 2 commits into from
Jun 30, 2020
Merged
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
4 changes: 2 additions & 2 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -8860,8 +8860,8 @@ def err_spawn_invalid_decl : Error<
"_Cilk_spawn not supported in a '%0Decl'">;
def err_spawn_spawn : Error<
"consecutive _Cilk_spawn tokens not allowed">;
def err_spawn_not_whole_expr : Error<
"_Cilk_spawn is not at statement level">;
def err_invalid_spawn_expr : Error<
"invalid _Cilk_spawn in expression">;
def err_cannot_spawn_builtin: Error<
"builtin function cannot be spawned">;
def err_cannot_spawn_function: Error<
Expand Down
13 changes: 3 additions & 10 deletions clang/lib/CodeGen/CGCilk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ void CodeGenFunction::DetachScope::StartDetach() {
}

void CodeGenFunction::DetachScope::CleanupDetach() {
if (DetachCleanedUp)
if (!DetachStarted || DetachCleanedUp)
return;

// Pop the sync region for the detached task.
Expand Down Expand Up @@ -380,13 +380,6 @@ static const Stmt *IgnoreImplicitAndCleanups(const Stmt *S) {
return Current;
}

static void FailedSpawnWarning(CodeGenFunction &CGF, SourceLocation SLoc) {
DiagnosticsEngine &Diags = CGF.CGM.getDiags();
unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Warning,
"Failed to produce spawn");
Diags.Report(SLoc, DiagID);
}

void CodeGenFunction::EmitCilkSpawnStmt(const CilkSpawnStmt &S) {
// Handle spawning of calls in a special manner, to evaluate
// arguments before spawn.
Expand All @@ -403,7 +396,7 @@ void CodeGenFunction::EmitCilkSpawnStmt(const CilkSpawnStmt &S) {
// Finish the detach.
if (IsSpawned) {
if (!CurDetachScope->IsDetachStarted())
FailedSpawnWarning(*this, S.getBeginLoc());
FailedSpawnWarning(S.getBeginLoc());
IsSpawned = false;
PopDetachScope();
}
Expand Down Expand Up @@ -441,7 +434,7 @@ LValue CodeGenFunction::EmitCilkSpawnExprLValue(const CilkSpawnExpr *E) {
// Finish the detach.
if (IsSpawned) {
if (!CurDetachScope->IsDetachStarted())
FailedSpawnWarning(*this, E->getExprLoc());
FailedSpawnWarning(E->getExprLoc());
IsSpawned = false;
PopDetachScope();
}
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4646,8 +4646,8 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) {
EmitStoreThroughLValue(RV, LV);

// Finish the detach.
assert(CurDetachScope && CurDetachScope->IsDetachStarted() &&
"Processing _Cilk_spawn of expression did not produce a detach.");
if (!(CurDetachScope && CurDetachScope->IsDetachStarted()))
FailedSpawnWarning(E->getRHS()->getExprLoc());
PopDetachScope();
IsSpawned = false;

Expand Down
12 changes: 6 additions & 6 deletions clang/lib/CodeGen/CGExprAgg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -890,8 +890,8 @@ void AggExprEmitter::VisitCilkSpawnExpr(CilkSpawnExpr *E) {
Visit(E->getSpawnedExpr());

// Pop the detach scope
assert(CGF.IsSpawned && CGF.CurDetachScope->IsDetachStarted() &&
"Processing _Cilk_spawn of expression did not produce a detach.");
if (!(CGF.IsSpawned && CGF.CurDetachScope->IsDetachStarted()))
CGF.FailedSpawnWarning(E->getExprLoc());
CGF.IsSpawned = false;
CGF.PopDetachScope();
}
Expand Down Expand Up @@ -1192,8 +1192,8 @@ void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
Visit(E->getRHS());
CGF.EmitAtomicStore(Dest.asRValue(), LHS, /*isInit*/ false);
if (CGF.IsSpawned) {
assert(CGF.CurDetachScope && CGF.CurDetachScope->IsDetachStarted() &&
"Processing _Cilk_spawn of expression did not produce a detach.");
if (!(CGF.CurDetachScope && CGF.CurDetachScope->IsDetachStarted()))
CGF.FailedSpawnWarning(E->getRHS()->getExprLoc());
CGF.IsSpawned = false;
CGF.PopDetachScope();
}
Expand All @@ -1217,8 +1217,8 @@ void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
EmitFinalDestCopy(E->getType(), LHS);

if (CGF.IsSpawned) {
assert(CGF.CurDetachScope && CGF.CurDetachScope->IsDetachStarted() &&
"Processing _Cilk_spawn of expression did not produce a detach.");
if (!(CGF.CurDetachScope && CGF.CurDetachScope->IsDetachStarted()))
CGF.FailedSpawnWarning(E->getRHS()->getExprLoc());
CGF.IsSpawned = false;
CGF.PopDetachScope();
}
Expand Down
8 changes: 4 additions & 4 deletions clang/lib/CodeGen/CGExprComplex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ class ComplexExprEmitter
CGF.PushDetachScope();
ComplexPairTy C = Visit(CSE->getSpawnedExpr());
if (DoSpawnedInit) {
assert(CGF.CurDetachScope && CGF.CurDetachScope->IsDetachStarted() &&
"Processing _Cilk_spawn of expression did not produce detach.");
if (!(CGF.CurDetachScope && CGF.CurDetachScope->IsDetachStarted()))
CGF.FailedSpawnWarning(CSE->getExprLoc());
LValue LV = LValueToSpawnInit;
EmitStoreOfComplex(C, LV, /*init*/ true);

Expand Down Expand Up @@ -1022,8 +1022,8 @@ LValue ComplexExprEmitter::EmitBinAssignLValue(const BinaryOperator *E,
EmitStoreOfComplex(Val, LHS, /*isInit*/ false);

// Finish the detach.
assert(CGF.CurDetachScope && CGF.CurDetachScope->IsDetachStarted() &&
"Processing _Cilk_spawn of expression did not produce detach.");
if (!(CGF.CurDetachScope && CGF.CurDetachScope->IsDetachStarted()))
CGF.FailedSpawnWarning(E->getRHS()->getExprLoc());
CGF.IsSpawned = false;
CGF.PopDetachScope();

Expand Down
8 changes: 4 additions & 4 deletions clang/lib/CodeGen/CGExprScalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -464,9 +464,9 @@ class ScalarExprEmitter
CGF.IsSpawned = true;
CGF.PushDetachScope();
Value *V = Visit(CSE->getSpawnedExpr());
if (!(CGF.CurDetachScope && CGF.CurDetachScope->IsDetachStarted()))
CGF.FailedSpawnWarning(CSE->getExprLoc());
if (DoSpawnedInit) {
assert(CGF.CurDetachScope && CGF.CurDetachScope->IsDetachStarted() &&
"Processing _Cilk_spawn of expression did not produce detach.");
LValue LV = LValueToSpawnInit;
CGF.EmitNullabilityCheck(LV, V, CSE->getExprLoc());
CGF.EmitStoreThroughLValue(RValue::get(V), LV, true);
Expand Down Expand Up @@ -3974,8 +3974,8 @@ Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {
CGF.EmitStoreThroughLValue(RValue::get(RHS), LHS);

// Finish the detach.
assert(CGF.CurDetachScope && CGF.CurDetachScope->IsDetachStarted() &&
"Processing _Cilk_spawn of expression did not produce detach.");
if (!(CGF.CurDetachScope && CGF.CurDetachScope->IsDetachStarted()))
CGF.FailedSpawnWarning(E->getRHS()->getExprLoc());
CGF.IsSpawned = false;
CGF.PopDetachScope();

Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CodeGen/CGStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1145,9 +1145,9 @@ void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) {
CurDetachScope->CleanupDetach();
cleanupScope.ForceCleanup();
if (IsSpawned) {
if (!(CurDetachScope && CurDetachScope->IsDetachStarted()))
FailedSpawnWarning(RV->getExprLoc());
// Pop the detach scope
assert(IsSpawned && CurDetachScope->IsDetachStarted() &&
"Processing _Cilk_spawn of expression did not produce a detach.");
IsSpawned = false;
PopDetachScope();
}
Expand Down
10 changes: 9 additions & 1 deletion clang/lib/CodeGen/CodeGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -1382,6 +1382,14 @@ class CodeGenFunction : public CodeGenTypeCache {
delete CurDetachScope;
}

/// Produce a warning that we failed to emit a spawn.
void FailedSpawnWarning(SourceLocation SLoc) {
DiagnosticsEngine &Diags = CGM.getDiags();
unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Warning,
"Failed to emit spawn");
Diags.Report(SLoc, DiagID);
}

// RAII for automatically popping detach scopes at the end of code-generating
// an expression.
class DetachScopeRAII {
Expand All @@ -1396,7 +1404,7 @@ class CodeGenFunction : public CodeGenTypeCache {
return;
CGF.PopDetachScope();
assert(CGF.CurDetachScope == StartingDetachScope &&
"Unexpected detach scope after processing AtomicExpr");
"Unexpected detach scope");
CGF.IsSpawned = false;
}
};
Expand Down
16 changes: 16 additions & 0 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12313,6 +12313,12 @@ static inline UnaryOperatorKind ConvertTokenKindToUnaryOpcode(
return Opc;
}

/// Check if Expr is an illegal spawn expression.
static void CheckForIllegalSpawn(Sema &S, Expr *Expr) {
if (isa<CilkSpawnExpr>(Expr->IgnoreImplicit()))
S.Diag(Expr->getExprLoc(), diag::err_invalid_spawn_expr);
}

/// DiagnoseSelfAssignment - Emits a warning if a value is assigned to itself.
/// This warning suppressed in the event of macro expansions.
static void DiagnoseSelfAssignment(Sema &S, Expr *LHSExpr, Expr *RHSExpr,
Expand Down Expand Up @@ -12538,6 +12544,11 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
}
}

// Check for illegal spawns
if (!BinaryOperator::isAssignmentOp(Opc))
CheckForIllegalSpawn(*this, RHS.get());
CheckForIllegalSpawn(*this, LHS.get());

switch (Opc) {
case BO_Assign:
ResultTy = CheckAssignmentOperands(LHS.get(), RHS, OpLoc, QualType());
Expand Down Expand Up @@ -12982,6 +12993,11 @@ static ExprResult BuildOverloadedBinOp(Sema &S, Scope *Sc, SourceLocation OpLoc,
break;
}

// Check for illegal spawns
if (!BinaryOperator::isAssignmentOp(Opc))
CheckForIllegalSpawn(S, RHS);
CheckForIllegalSpawn(S, LHS);

// Find all of the overloaded operators visible from this
// point. We perform both an operator-name lookup from the local
// scope and an argument-dependent lookup based on the types of
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Cilk/spawn-builtin.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ void spawn_trap() {
// CHECK-NEXT: sync within %[[SYNCREG]]

void spawn_assume() {
_Cilk_spawn __builtin_assume(0); // expected-warning{{Failed to produce spawn}}
_Cilk_spawn __builtin_assume(0); // expected-warning{{Failed to emit spawn}}
}

// It doesn't make sense to spawn an assume, so we expect not to find any
Expand Down
15 changes: 15 additions & 0 deletions clang/test/Cilk/spawn-expr.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Check the spawning of builtins.
//
// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -fopencilk -verify -ftapir=none -S -emit-llvm -o - | FileCheck %s

int g(int);

int f() {
int x = _Cilk_spawn 0; // expected-warning {{Failed to emit spawn}}
g(_Cilk_spawn 7); // expected-warning {{Failed to emit spawn}}
return _Cilk_spawn 1; // expected-warning {{no parallelism from a '_Cilk_spawn' in a return statement}} expected-warning {{Failed to emit spawn}}
}

// CHECK-LABEL: define {{.*}}i32 @f(
// CHECK-NOT: detach

6 changes: 6 additions & 0 deletions clang/test/Cilk/spawntest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,9 @@ int spawn_assign_eval_order_tests(int n) {
Arr[i++] += _Cilk_spawn bar(i); // expected-warning {{unsequenced modification and access to 'i'}}
return 0;
}

void invalid_spawn_expr() {
int x = 0;
x + _Cilk_spawn 7; // expected-warning {{expression result unused}} expected-error {{invalid _Cilk_spawn in expression}}
int y = x + _Cilk_spawn 7; // expected-error {{invalid _Cilk_spawn in expression}}
}