This is an archive of the discontinued LLVM Phabricator instance.

Implementing 'If statement with Initializer'
ClosedPublic

Authored by AntonBikineev on Jun 29 2016, 2:45 AM.

Details

Summary

Here is an implementation of a feature 'if (init; condition)', proposed in p0305r0 and accepted at the last meeting in Oulu:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0305r0.html

Diff Detail

Event Timeline

AntonBikineev retitled this revision from to Implemeting 'If statement with Initializer'.
AntonBikineev updated this object.
AntonBikineev added reviewers: rsmith, mclow.lists.
AntonBikineev retitled this revision from Implemeting 'If statement with Initializer' to Implementing 'If statement with Initializer'.
mclow.lists edited edge metadata.Jun 29 2016, 9:52 AM

I think you should add "cfe-commits" to the subscribers.

AntonBikineev edited edge metadata.
AntonBikineev added a subscriber: cfe-commits.
rsmith requested changes to this revision.Jun 29 2016, 2:27 PM
rsmith edited edge metadata.

The proposal has changed since the pre-meeting mailing, and now covers switch as well as if. You also need to handle the expression-statement form of init-statement.

As it happens, I've also been working on this proposal, and the bit that you're getting wrong here (the parsing side) is the part that I've finished. I've committed that as r274169; if you rebase your Sema changes on top of that (and add support for switch), we can get this change committed to finish off the implementation.

We'll also need some tests before this can be committed.

Thank you!

lib/Parse/ParseStmt.cpp
1062–1075

We should try to only walk over the tokens once to identify whether this is a condition declaration, a simple-declaration of an init-statement, or an expression.

lib/Parse/ParseTentative.cpp
77–79

This is not correct; TryParseSimpleDeclaration usually stops long before it reaches the end of the simple-declaration, so this will give false negatives in lots of cases.

This revision now requires changes to proceed.Jun 29 2016, 2:27 PM

@rsmith,

This is not correct; TryParseSimpleDeclaration usually stops long before it reaches the end of the simple-declaration, so this will give false negatives in lots of cases.

Yes, I noticed that, that's why I changed use of TryParseSimpleDeclaration to something easier in last revision.

Thanks for reply, Richard. The revision you sent looks great, I should have updated my working copy before :)
Anyways, there are not too much of changes to Sema/AST stuff, I just applied them on top of yours, added the same for SwitchStmt. I'll update the test you put according to my changes tomorrow.

AntonBikineev edited edge metadata.
AntonBikineev edited edge metadata.

Test Parser/cxx1z-init-statement.cpp has been updated according to Sema changes

There are a few missing pieces here:

  1. Analysis/CFG.cpp needs to be taught to build a correct CFG for these. You can test this with an example like 'if (bool b; b)' which should give a -Wuninitialized warning.
  2. AST/ExprConstant.cpp needs to be taught to perform constant evaluation for these properly.
  3. More test coverage. In addition for test cases for the above two cases, please also add some tests to test/CodeGenCXX to test that we emit correct code for the expression and declaration form of these constructs, for both if and switch, and add a test that checks that the extra statement round-trips through an AST file properly (see test/PCH for some examples).

@rsmith,
Thanks for the comments, I've addressed them (except for tests, they are to be added asap). I'm especially not sure about changes in CFG.cpp, could you verify please?

@rsmith,
I've added some tests for c++1z init statement. Please let me know if there is anything else I should add or change.

This looks really good. Some minor comments then this is ready to commit.

include/clang/AST/Stmt.h
890

* on the right, please (you can run clang-format over the patch to handle minor details like this).

lib/CodeGen/CGStmt.cpp
565

Too much indentation here.

lib/Sema/SemaStmt.cpp
512

Please also delete this diagnostic from include/clang/Basic/DiagnosticSemaKinds.td.

test/CodeGenCXX/cxx1z-init-statement.cpp
1 ↗(On Diff #63056)

Probably best to run this with -std=c++1z, but it's not a big deal.

5 ↗(On Diff #63056)

Please use a placeholder for the SSA variables here:

%[[A:.*]] = alloca i32
store i32 5, i32* %[[A]]

... so that this test doesn't depend on whether we generate names for these values or not (debug and release builds of Clang differ here in some cases, and it's not a salient part of the test).

test/PCH/cxx1z-init-statement.cpp
8–9 ↗(On Diff #63056)

Maybe change this test to use constexpr and static_assert so that we can test that the behavior is correct, not just that it doesn't crash.

test/SemaCXX/cxx1z-init-statement-warn-unused.cpp
6 ↗(On Diff #63056)

Maybe add a test like this:

int a;
if (a = 0; a) {}

... to make sure we actually visit the init-statement.

AntonBikineev updated this object.

@rsmith,
Richard, again, thank you for guiding. I've addressed your comments.

removed a leftover from parser/cxx1z-init-stmt.cpp test

Moved stars to the right side of declarations

rsmith accepted this revision.Jul 13 2016, 5:18 PM
rsmith edited edge metadata.

Thank you again! I've fixed some over-long lines and committed this as r275350.

This revision is now accepted and ready to land.Jul 13 2016, 5:18 PM
rsmith closed this revision.Jul 13 2016, 5:18 PM