clang++-3.3 reject valid ?

Hi!

The following code
$ cat -n x.ii
     1 extern "C" typedef struct
     2 {
     3 volatile struct
     4 {
     5 } fields;
     6 }
     7 CSPHandleState;
     8 typedef struct
     9 {
    10 CSPHandleState state;
    11 }
    12 CSPHandle;
    13 CSPHandle a;
    14 void
    15 fn1 ()
    16 {
    17 CSPHandleState b;
    18 b = a.state;
    19 }

rejected by clang++
$ /home/dimhen/build/csa/Release+Asserts/bin/clang++ -fsyntax-only -x c++ x.ii
x.ii:1:20: error: member function 'operator=' not viable: 'this'
argument has type
      'volatile struct <anonymous struct at x.ii:3:14>', but function
is not marked
      volatile
extern "C" typedef struct
                   ^~~~~~
x.ii:3:14: note: 'operator=' declared here
    volatile struct
             ^
x.ii:18:7: note: implicit default copy assignment operator for
'CSPHandleState' first
      required here
    b = a.state;
      ^
1 error generated.

$ /home/dimhen/build/csa/Release+Asserts/bin/clang++ -v
clang version 3.3 (trunk 179273)
Target: x86_64-unknown-linux-gnu
Thread model: posix

but gcc accept this
$ g++ -Wall -Wextra -fsyntax-only x.ii
[dimhen@dim clang]$ echo $?
0

gcc versions:
gcc version 4.7.2 20121109 (Red Hat 4.7.2-8) (GCC)
gcc version 4.9.0 20130411 (experimental) [trunk revision 197693] (GCC)

Original file (not the reduced testcase) was successfully compiled with
many gcc versions (many versions from 3.2.3 to 4.9), xlc (AIX 5/6/7),
suncc (Solaris 9/10 x64/sparc), MS Visual Studio (many versions from
2005 to 2012)

So, my question is: what is right behavior?

Thank You,
Dmitry

Seems like a case of accepts-invalid in other compilers. If you do the
copy explicitly rather than via the implicit copy ctor, it fails:

struct foo { };
volatile foo f;
f = foo(); // passing ‘volatile foo’ as ‘this’ argument of ‘foo&
foo::operator=(const foo&)’ discards qualifiers [-fpermissive]

(additional errors occur if you try to copy from a volatile as well as
to a volatile)

In fact, while reducing your test case, I even managed to ICE GCC:

truct foo { };
  typedef struct
  {
      volatile foo fields;
  }
  CSPHandleState;
  CSPHandleState a;
  void
  fn1 ()
  {
      CSPHandleState b;
      b.fields = foo();
  }

Thank You, David

Dmitry

g++ ICE reported as 56961 – stack overflow in gimplifier with volatile field

Thanks again, David

Dmitry