static initialization of global namespace scope constexpr objects

Hello,

I am perusing through N2235 (Generalized Constant Expressions) and was trying
out the example on page 8, namely:

struct complex {
  constexpr complex(double r, double i) : re(r), im(i) { }
  constexpr double real() { return re; }
  constexpr double imag() { return im; }
private:
  double re;
  double im;
};
constexpr complex I(0, 1); // OK -- literal complex

constexpr double d = I.real(); // added by me

I generated the assembler output with my clang++ build:

$ /d/llvm_workspace/build/Debug+Asserts/bin/clang++ -v
clang version 3.2 (trunk 157115) (llvm/trunk 157155)
Target: i686-pc-mingw32
Thread model: posix

and it churned out the following:

  .data
  .align 8
__ZL1I:
  .quad 0
  .quad 4607182418800017408

  .align 8
__ZL1d:
  .quad 0

However, I was hoping that in the regular mode, static initialization would help
put this in a readonly data section as the gcc 4.6.2 does (with the same file):

  .file "constexpr.cpp"
  .data
  .align 8
__ZL1I:
  .long 0
  .long 0
  .long 0
  .long 1072693248
  .section .rdata,"dr"
  .align 8
__ZL1d:
  .space 8
  
GCC is not perfect as it puts only the double in read-only memory. I am not sure
why this is so. However, I am unable to fathom clang's behavior here. Is my
understanding of constexpr at fault here? In the ideal case, shouldn't both I
and d be move to ro-section?

Also, does 3.6.2/3 mandate that static initialization will not occur for objects
with extern linkage? IOW, the following:

extern constexpr complex I(0, 1); // OK -- literal complex

will always require dynamic initialization and can thus never be in a
ro-section?

Regards,
Suman

Hello,

I am perusing through N2235 (Generalized Constant Expressions) and was trying
out the example on page 8, namely:

struct complex {
constexpr complex(double r, double i) : re(r), im(i) { }
constexpr double real() { return re; }
constexpr double imag() { return im; }
private:
double re;
double im;
};
constexpr complex I(0, 1); // OK – literal complex

constexpr double d = I.real(); // added by me

I generated the assembler output with my clang++ build:

$ /d/llvm_workspace/build/Debug+Asserts/bin/clang++ -v
clang version 3.2 (trunk 157115) (llvm/trunk 157155)
Target: i686-pc-mingw32
Thread model: posix

and it churned out the following:

.data
.align 8
__ZL1I:
.quad 0
.quad 4607182418800017408

.align 8
__ZL1d:
.quad 0

This looks like a backend issue: it appears that we don’t support .rodata when targeting i686-pc-mingw32. For i686-linux-gnu, we produce this:

.file “constexpr.cpp”
.type _ZL1I,@object # @_ZL1I
.section .rodata,“a”,@progbits
.align 4
_ZL1I:
.quad 0 # double 0.000000e+00

(0x0)

.quad 4607182418800017408 # double 1.000000e+00

(0x3ff0000000000000)

.size _ZL1I, 16

.type _ZL1d,@object # @_ZL1d
.align 8
_ZL1d:
.quad 0 # double 0.000000e+00

(0x0)

.size _ZL1d, 8

.section “.note.GNU-stack”,"",@progbits

Also, does 3.6.2/3 mandate that static initialization will not occur for objects
with extern linkage?

3.6.2/3 doesn’t mandate anything. Instead, it gives the implementation permission to transform dynamic initialization into static initialization in some circumstances.

IOW, the following:

extern constexpr complex I(0, 1); // OK – literal complex

will always require dynamic initialization and can thus never be in a
ro-section?

No, static initialization (in particular, constant initialization) is required here, because the variable is constexpr. Clang (well, LLVM) emits this variable into an RO section on targets where it knows how to do so.

[...]

This looks like a backend issue: it appears that we don't support .rodata
when targeting i686-pc-mingw32.

[...]

Clang (well, LLVM) emits
this variable into an RO section on targets where it knows how to do so.

Is there a bug/feature request that tracks this issue? Are there plans
to work on mingw specific issues for some release in the near future?

Regards,
Suman

This question is likely to get a better response on llvm-dev.

Right. Thank you! I will move this thread to llvm-dev.

Regards,
Suman