aaronpuchert added a comment.

Yeah, we should get this over the line. I'm still not quite sure where to put 
the check. Reading @rsmith's comment again, SemaInit might perhaps be 
acceptable for now, except that I should add the additional tests (in case we 
don't have them already).

I think we also need D113837 <https://reviews.llvm.org/D113837>, because 
otherwise `void` is being used as a placeholder. In any event, I should at 
least rebase the patches and check if they still work.



================
Comment at: clang/lib/Sema/SemaInit.cpp:1311-1319
+  } else if (DeclType->isVoidType()) {
+    // [expr.type.conv]p2: Otherwise, if the type is cv void and the
+    // initializer is () or {} (after pack expansion, if any), the expression
+    // is a prvalue of type void that performs no initialization.
+    if (IList->getNumInits() > 0) {
+      if (!VerifyOnly)
+        SemaRef.Diag(IList->getBeginLoc(), diag::err_init_list_void_nonempty);
----------------
rsmith wrote:
> Hm, this seems like the wrong place for this check, given the wording -- the 
> language rule is specific to functional casts, and shouldn't apply to 
> initialization of `void`-typed objects in general -- but perhaps it's the 
> best place we have (and I think we deal with the `void()` case here in 
> SemaInit too). Please at least make sure that we still properly reject things 
> like:
> ```
> void f() {
>   return {};
> }
> ```
> We also need to decide whether to accept the compound-literal form of this:
> ```
> void g() {
>   (void){};
> }
> ```
> GCC trunk does, but I'm not sure whether that's intentional or an oversight. 
> We certainly shouldn't accept that (without a diagnostic, at least) in C.
> Hm, this seems like the wrong place for this check, given the wording -- the 
> language rule is specific to functional casts, and shouldn't apply to 
> initialization of `void`-typed objects in general -- but perhaps it's the 
> best place we have (and I think we deal with the `void()` case here in 
> SemaInit too).

So we should unconditionally allow it here and check later in 
`CastOperation::CheckCXXCStyleCast`? It handles `void` target types already, 
but only for [expr.static.cast]p6:
> Any expression can be explicitly converted to type cv void, in which case it 
> becomes a discarded-value expression ([expr.prop]).
Indeed we don't create a `CXXFunctionalCastExpr` for `void()` but a 
`CXXScalarValueInitExpr` (though probably for legacy reasons). But it should be 
the proper place, I agree.

> Please at least make sure that we still properly reject things like:
> ```
> void f() {
>   return {};
> }
> ```

That fails as before with
```
<stdin>:2:3: error: void function 'f' must not return a value
  return {};
  ^      ~~
```

> We also need to decide whether to accept the compound-literal form of this:
> ```
> void g() {
>   (void){};
> }
> ```

That is rejected in C and C++ with
```
<stdin>:2:3: error: variable has incomplete type 'void'
  (void){};
  ^~~~~~~~
```


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D113838/new/

https://reviews.llvm.org/D113838

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D113838: Sema: Don... Shafik Yaghmour via Phabricator via cfe-commits
    • [PATCH] D113838: Sema... Aaron Puchert via Phabricator via cfe-commits

Reply via email to