<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - -Wcomma does not play well with -std=c89"
href="https://bugs.llvm.org/show_bug.cgi?id=32370">32370</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>-Wcomma does not play well with -std=c89
</td>
</tr>
<tr>
<th>Product</th>
<td>clang
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>All
</td>
</tr>
<tr>
<th>OS</th>
<td>All
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>enhancement
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>Frontend
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedclangbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>sneves@dei.uc.pt
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>Beginning with an offending sample:
```
void f(void) {
int i = 0, j = 0;
for(;i < 10; ++i, ++j) {}
}
```
Compiling with `clang -std=c89 -Wcomma` we get
```
test.c:3:19: warning: possible misuse of comma operator here [-Wcomma]
for(;i < 10; ++i, ++j) {}
^
test.c:3:16: note: cast expression to void to silence warning
for(;i < 10; ++i, ++j) {}
^~~
(void)( )
```
However, this example clearly belongs to the whitelisted class of comma
operator cases, and indeed in C++ and C99 modes clang behaves as expected.
I looked a little bit into why this happens, and the culprit appears to be the
following. The whitelisting of expressions happens in
[lib/Sema/SemaExpr.cpp](<a href="https://github.com/llvm-mirror/clang/blob/9a1877f04c1a225ff4acae5524d18be91f7fba3f/lib/Sema/SemaExpr.cpp#L10383-L10395">https://github.com/llvm-mirror/clang/blob/9a1877f04c1a225ff4acae5524d18be91f7fba3f/lib/Sema/SemaExpr.cpp#L10383-L10395</a>):
```
// Scope isn't fine-grained enough to whitelist the specific cases, so
// instead, skip more than needed, then call back into here with the
// CommaVisitor in SemaStmt.cpp.
// The whitelisted locations are the initialization and increment portions
// of a for loop. The additional checks are on the condition of
// if statements, do/while loops, and for loops.
const unsigned ForIncrementFlags =
Scope::ControlScope | Scope::ContinueScope | Scope::BreakScope;
const unsigned ForInitFlags = Scope::ControlScope | Scope::DeclScope;
const unsigned ScopeFlags = getCurScope()->getFlags();
if ((ScopeFlags & ForIncrementFlags) == ForIncrementFlags ||
(ScopeFlags & ForInitFlags) == ForInitFlags)
return;
```
But, in
[lib/Parse/ParseStmt.cpp](<a href="https://github.com/llvm-mirror/clang/blob/9a1877f04c1a225ff4acae5524d18be91f7fba3f/lib/Parse/ParseStmt.cpp#L1532-L1549">https://github.com/llvm-mirror/clang/blob/9a1877f04c1a225ff4acae5524d18be91f7fba3f/lib/Parse/ParseStmt.cpp#L1532-L1549</a>),
we have that these flags are only activated in C99 or C++ modes:
```
// C99 6.8.5p5 - In C99, the for statement is a block. This is not
// the case for C90. Start the loop scope.
//
// ...
//
unsigned ScopeFlags = 0;
if (C99orCXXorObjC)
ScopeFlags = Scope::DeclScope | Scope::ControlScope;
```
Therefore, it appears using these flags will not work in C90 to whitelist for
expressions.</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>