This is an archive of the discontinued LLVM Phabricator instance.

[Sema] add cast from IncompleteArrayType to ConstantArrayType in TryReferenceListInitialization
AbandonedPublic

Authored by HerrCai0907 on May 25 2023, 4:04 PM.

Details

Summary

Fixed: https://github.com/llvm/llvm-project/issues/62945
c++20 supports "Permit conversions to arrays of unknown bound".
This need additional cast from IncompleteArrayType to ConstantArrayType
in TryReferenceListInitialization

Diff Detail

Event Timeline

HerrCai0907 created this revision.May 25 2023, 4:04 PM
Herald added a project: Restricted Project. · View Herald TranscriptMay 25 2023, 4:04 PM
HerrCai0907 requested review of this revision.May 25 2023, 4:04 PM
Herald added a project: Restricted Project. · View Herald TranscriptMay 25 2023, 4:04 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript

Thank you for the patch! Please apply clang-format at least one of pre-commit failures is due to that.

rnk added inline comments.
clang/lib/CodeGen/CGCall.cpp
4376 ↗(On Diff #525854)

I think this discards too much information about pointer types. I think it would treat two pointers with interestingly different qualifiers differently. Consider, perhaps, a mismatch in pointer address spaces, which are passed differently (think __ptr32 __ptr64).

I think there is probably some other way to get the type of the parameter after pointer decay. I would ask @efriedma since he's the current IRGen owner or @rjmccall since I think he may have added this prototype assertion originally, I just moved the code around.

Relevant bit of the AST:

`-ExprWithCleanups 0xd16a780 <line:6:3, col:8> 'void':'void'
  `-CXXOperatorCallExpr 0xd16a678 <col:3, col:8> 'void':'void' '()'
    |-ImplicitCastExpr 0xd16a5a8 <col:4, col:8> 'void (*)(int (&&)[]) const' <FunctionToPointerDecay>
    | `-DeclRefExpr 0xd16a528 <col:4, col:8> 'void (int (&&)[]) const' lvalue CXXMethod 0xd14f7f8 'operator()' 'void (int (&&)[]) const'
    |-ImplicitCastExpr 0xd16a5e8 <col:3> 'const (lambda at <stdin>:5:12)' lvalue <NoOp>
    | `-DeclRefExpr 0xd16a460 <col:3> '(lambda at <stdin>:5:12)':'(lambda at <stdin>:5:12)' lvalue Var 0xd14f628 'f' '(lambda at <stdin>:5:12)':'(lambda at <stdin>:5:12)'
    `-MaterializeTemporaryExpr 0xd16a660 <col:5, col:7> 'int[1]' xvalue
      `-InitListExpr 0xd16a600 <col:5, col:7> 'int[1]'
        `-ImplicitCastExpr 0xd16a640 <col:6> 'int' <LValueToRValue>
          `-DeclRefExpr 0xd16a480 <col:6> 'int' lvalue ParmVar 0xd14f3a8 'a' 'int'

At first glance, I'd consider this a problem with the AST: there should be a no-op cast from int[1] to int[]. We generate such a cast for the following:

void foo(int a) {
  auto f = [](int(&&)[]) {};
  int aa[1] = {a};
  f(static_cast<int(&&)[1]>(aa));
}

Yeah, I agree with Eli, there should be a cast here.

HerrCai0907 retitled this revision from [CodeGen] add additional cast when checking call arguments to [Sema] add cast from IncompleteArrayType to ConstantArrayType in TryReferenceListInitialization.May 26 2023, 11:53 PM
HerrCai0907 edited the summary of this revision. (Show Details)
erichkeane added inline comments.May 30 2023, 6:38 AM
clang/lib/Sema/SemaInit.cpp
4433

Is VK_XValue correct here? The standards quote says it is a PRValue?

HerrCai0907 added inline comments.May 30 2023, 12:43 PM
clang/lib/Sema/SemaInit.cpp
4433

The original text of standards in https://eel.is/c++draft/dcl.init.list is

List-initialization of an object or reference of type T is defined as follows:

3.10 Otherwise, if T is a reference type, a prvalue is generated. The prvalue initializes its result object by copy-list-initialization from the initializer list. The prvalue is then used to direct-initialize the reference. The type of the prvalue is the type referenced by T, unless T is “reference to array of unknown bound of U”, in which case the type of the prvalue is the type of x in the declaration U x[] H, where H is the initializer list.

My understand is that a PRValue is generated by XValue initialization list.

By the way, I have try to use VK_PRValue, it cause the assert failed:
can't implicitly cast glvalue to prvalue with this cast kind: NoOp