Attributes and Clone Functionality

It appears that attributes are not propagated from CXXRecordDecls to ClassTemplateSpecializationDecls, even when the attribute has set the Clone value to 1. The text above the Clone value in Attr.td seems to indicate that if it is set to true attributes are propagated to template instantiations. Is this a bug, or is it intended behavior and I’m missing something?

  • Chris

It appears that attributes are not propagated from CXXRecordDecls to
ClassTemplateSpecializationDecls, even when the attribute has set the Clone
value to 1. The text above the Clone value in Attr.td seems to indicate
that if it is set to true attributes are propagated to template
instantiations. Is this a bug, or is it intended behavior and I'm missing
something?

Can you provide an example of what you're seeing? This WFM:

$ echo 'template<typename T> struct __attribute__((packed)) S { char c; T
t; }; S<int> s;' | ./build/bin/clang -x c++ - -Xclang -ast-dump
TranslationUnitDecl 0x56230f0 <<invalid sloc>>

-TypedefDecl 0x5623630 <<invalid sloc>> __int128_t '__int128'
-TypedefDecl 0x5623690 <<invalid sloc>> __uint128_t 'unsigned __int128'
-TypedefDecl 0x5623a50 <<invalid sloc>> __builtin_va_list '__va_list_tag

[1]'

-ClassTemplateDecl 0x5623be0 <<stdin>:1:1, col:70> S
>-TemplateTypeParmDecl 0x5623aa0 <col:10, col:19> typename T

*| |-CXXRecordDecl 0x5623b50 <col:22, col:70> struct S*
*| | |-PackedAttr 0x5651a30 <col:44>*

> >-CXXRecordDecl 0x5651a70 <col:22, col:53> struct S
> >-FieldDecl 0x5651b10 <col:57, col:62> c 'char'
> `-FieldDecl 0x5651b70 <col:65, col:67> t 'T'

*| `-ClassTemplateSpecializationDecl 0x5651bd0 <col:1, col:70> struct S*

  >-TemplateArgument type 'int'

*| |-PackedAttr 0x5651de0 <col:44>*

  >-CXXRecordDecl 0x5651e80 prev 0x5651bd0 <col:22, col:53> struct S
  >-FieldDecl 0x5651f10 <col:57, col:62> c 'char'
  >-FieldDecl 0x5651fa0 <col:65, col:67> t 'int':'int'
  >-CXXConstructorDecl 0x5652010 <col:53> S 'void (void)' inline

noexcept-unevaluated 0x5652010

  > `-CompoundStmt 0x5652310 <col:53>
  `-CXXConstructorDecl 0x5652170 <col:53> S 'void (const struct S<int>

&)' inline noexcept-unevaluated 0x5652170

    `-ParmVarDecl 0x56522b0 <col:53> 'const struct S<int> &'

`-VarDecl 0x5651d80 <col:73, col:80> s 'S<int>':'struct S<int>'
  `-CXXConstructExpr 0x5652328 <col:80> 'S<int>':'struct S<int>' 'void
(void)'

After more discussion: the problem is that attributes on class templates
are instantiated with the definition of the class template specialization,
not with its declaration. That's fine for some attributes (like packed,
aligned, transparent_union) but wrong for others (deprecated, may_alias,
visibility, lockable, consumed).