[PATCH] D105756: [clang] C++98 implicit moves are back with a vengeance

Artem Dergachev via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 7 14:52:30 PDT 2021


NoQ added a comment.

It looks like this commit causes unexpected changes in non-C++ code. Eg., in this tiny reproducer (that uses the non-standard "blocks" feature but is otherwise plain C):

  typedef struct {
    int x;
  } S;
  
  void foo() {
    ^{
      S s;
      return s;
    };
  }

I'm suddenly seeing C++-specific items in the AST that shouldn't show up in C (xvalues, NRVO, etc.):

`$ clang -x c -Xclang -ast-dump test.c`

  ...
  `-FunctionDecl 0x7fc55288aa88 <line:5:1, line:10:1> line:5:6 foo 'void ()'
    `-CompoundStmt 0x7fc55288aec0 <col:12, line:10:1>
      `-BlockExpr 0x7fc55288aea8 <line:6:3, line:9:3> 'S (^)(void)'
        `-BlockDecl 0x7fc55288ab70 <line:6:3, line:9:3> line:6:3
          |-CompoundStmt 0x7fc55288adc8 <col:4, line:9:3>
          | |-DeclStmt 0x7fc55288acd8 <line:7:5, col:8>
          | | `-VarDecl 0x7fc55288ac70 <col:5, col:7> col:7 used s 'S':'S' nrvo
          | `-ReturnStmt 0x7fc55288adb0 <line:8:5, col:12>
          |   `-ImplicitCastExpr 0x7fc55288ad98 <col:12> 'S':'S' <LValueToRValue>
          |     `-ImplicitCastExpr 0x7fc55288ad80 <col:12> 'S':'S' xvalue <NoOp>
          |       `-ImplicitCastExpr 0x7fc55288ad68 <col:12> 'S':'S' <LValueToRValue>
          |         `-DeclRefExpr 0x7fc55288acf0 <col:12> 'S':'S' lvalue Var 0x7fc55288ac70 's' 'S':'S'
          `-VarDecl 0x7fc55288ac70 <line:7:5, col:7> col:7 used s 'S':'S' nrvo

The double implicit lvalue-to-rvalue cast looks incorrect as well (there isn't an extra dereference here).

Here's how the old AST looks like:

  ...
  `-FunctionDecl 0x7fb594079e88 <line:5:1, line:10:1> line:5:6 foo 'void ()'
    `-CompoundStmt 0x7fb59407a230 <col:12, line:10:1>
      `-BlockExpr 0x7fb59407a218 <line:6:3, line:9:3> 'S (^)(void)'
        `-BlockDecl 0x7fb594079f70 <line:6:3, line:9:3> line:6:3
          |-CompoundStmt 0x7fb59407a138 <col:4, line:9:3>
          | |-DeclStmt 0x7fb59407a0d8 <line:7:5, col:8>
          | | `-VarDecl 0x7fb59407a070 <col:5, col:7> col:7 used s 'S':'S'
          | `-ReturnStmt 0x7fb59407a128 <line:8:5, col:12>
          |   `-ImplicitCastExpr 0x7fb59407a110 <col:12> 'S':'S' <LValueToRValue>
          |     `-DeclRefExpr 0x7fb59407a0f0 <col:12> 'S':'S' lvalue Var 0x7fb59407a070 's' 'S':'S'
          `-VarDecl 0x7fb59407a070 <line:7:5, col:7> col:7 used s 'S':'S'

I don't think this is intended. @mizvekov, do you think you can add more hard checks to make sure it's constrained to C++? (Or maybe there's another, more precise solution?)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D105756



More information about the cfe-commits mailing list