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

Bluesim: Add braces to some if-stmts in generated C++ #691

Merged
merged 1 commit into from
Apr 9, 2024
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
20 changes: 17 additions & 3 deletions src/comp/CCSyntax.hs
Original file line number Diff line number Diff line change
Expand Up @@ -675,10 +675,24 @@ instance PPrint CCFragment where
pPrint d p (CPPInclude file True) = text ("#include <" ++ file ++ ">")
pPrint d p (CPPInclude file False) = text ("#include \"" ++ file ++ "\"")
pPrint d p (CIf c th Nothing) =
(text "if (") <> (pp c) <> (text ")") $+$ (printClauseOrBlock th)
-- If the true-arm is a nested if-stmt with an else-clause,
-- possibly under layers of for-stmts with single elements,
-- then braces are needed to avoid an ambiguous-else warning
let needsBraces (CIf _ _ (Just _)) = True
needsBraces (CFor _ _ _ b) = needsBraces b
needsBraces _ = False
th' = if (needsBraces th) then CBlock [th] else th
in (text "if (") <> (pp c) <> (text ")") $+$ (printClauseOrBlock th')
pPrint d p (CIf c th (Just el)) =
(text "if (") <> (pp c) <> (text ")") $+$
(printClauseOrBlock th) $+$ (text "else") $+$ (printClauseOrBlock el)
-- If the true-arm is a nested if-stmt without an else-clause,
-- possibly under layers of for-stmts with single elements,
-- then braces are needed for correct parsing
let needsBraces (CIf _ _ Nothing) = True
needsBraces (CFor _ _ _ b) = needsBraces b
needsBraces _ = False
th' = if (needsBraces th) then CBlock [th] else th
in (text "if (") <> (pp c) <> (text ")") $+$
(printClauseOrBlock th') $+$ (text "else") $+$ (printClauseOrBlock el)
pPrint d p (CSwitch idx arms deflt) =
let ppArm (n, blk) = (text "case") <+> (pp n) <> (text ":") $+$
nest 2 (vsep (map printStmt blk))
Expand Down
28 changes: 28 additions & 0 deletions testsuite/bsc.bluesim/misc/NestedIfBraces.bsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@


ActionValue #(Bit #(32)) cur_cycle = actionvalue
Bit #(32) t <- $stime;
if (genVerilog)
t = t + 5;
return t / 10;
endactionvalue;

(* synthesize *)
module sysNestedIfBraces ();

Reg #(Bit #(4)) cfg_verbosity <- mkReg (1);

Reg #(Bool) rg_state <- mkReg (False);

rule rl_display (! rg_state);
if (cfg_verbosity != 0)
$display ("%0d: display", cur_cycle);
rg_state <= True;
endrule

rule rl_finish (rg_state);
$finish (0);
endrule

endmodule

10 changes: 10 additions & 0 deletions testsuite/bsc.bluesim/misc/misc.exp
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,13 @@ compile_object_pass AVMethBDPIWithReset.bsv
copy c_func.c.keep c_func.c
link_objects_pass {} sysAVMethBDPIWithReset {c_func.c}
}

# GitHub #442: Nested if-else needs braces when possible ambiguity
# This tests "if (!RST) if (cond) e1 else e2" in the code for
# executing system tasks.
if {$ctest == 1} {
compile_object_pass NestedIfBraces.bsv
link_objects_pass {} sysNestedIfBraces
# Test that there were no warnings during C++ compilation
compare_file [make_bsc_ccomp_output_name sysNestedIfBraces]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Bluesim object created: sysNestedIfBraces.{h,o}
Bluesim object created: model_sysNestedIfBraces.{h,o}
Simulation shared library created: sysNestedIfBraces.cexe.so
Simulation executable created: sysNestedIfBraces.cexe