Skip to content

Commit

Permalink
[Sema] Fix PR22637 - IndirectFieldDecl's discard qualifiers during te…
Browse files Browse the repository at this point in the history
…mplate instantiation.

Summary:
Currently Clang fails to propagate qualifiers from the `CXXThisExpr` to the rebuilt `FieldDecl` for IndirectFieldDecls. For example:

```
template <class T> struct Foo {
  struct { int x; };
  int y;
  void foo() const { 
      static_assert(__is_same(int const&, decltype((y))));
      static_assert(__is_same(int const&, decltype((x)))); // assertion fails
  }
};
template struct Foo<int>;
```

The fix is to delegate rebuilding of the MemberExpr to `BuildFieldReferenceExpr` which correctly propagates the qualifiers.

Reviewers: rsmith, lebedev.ri, aaron.ballman, bkramer, rjmccall

Reviewed By: rjmccall

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D45412

llvm-svn: 329517
  • Loading branch information
EricWF committed Apr 8, 2018
1 parent 0eb86c8 commit 8439361
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 6 deletions.
10 changes: 5 additions & 5 deletions clang/lib/Sema/TreeTransform.h
Expand Up @@ -2250,11 +2250,11 @@ class TreeTransform {
if (BaseResult.isInvalid())
return ExprError();
Base = BaseResult.get();
ExprValueKind VK = isArrow ? VK_LValue : Base->getValueKind();
MemberExpr *ME = new (getSema().Context)
MemberExpr(Base, isArrow, OpLoc, Member, MemberNameInfo,
cast<FieldDecl>(Member)->getType(), VK, OK_Ordinary);
return ME;

CXXScopeSpec EmptySS;
return getSema().BuildFieldReferenceExpr(
Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Member),
DeclAccessPair::make(FoundDecl, FoundDecl->getAccess()), MemberNameInfo);
}

CXXScopeSpec SS;
Expand Down
40 changes: 40 additions & 0 deletions clang/test/SemaCXX/PR22637.cpp
@@ -0,0 +1,40 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s

// expected-no-diagnostics

void check(int&) = delete;
void check(int const&) { }

template <typename>
struct A {
union {
int b;
};
struct {
int c;
};
union {
struct {
union {
struct {
struct {
int d;
};
};
};
};
};
int e;
void foo() const {
check(b);
check(c);
check(d);
check(d);
check(e);
}
};

int main(){
A<int> a;
a.foo();
}
2 changes: 1 addition & 1 deletion clang/test/SemaCXX/cxx0x-nontrivial-union.cpp
Expand Up @@ -110,7 +110,7 @@ namespace optional {
}

explicit operator bool() const { return has; }
T &operator*() const { return value; }
T &operator*() { return value; }
};

optional<non_trivial> o1;
Expand Down

0 comments on commit 8439361

Please sign in to comment.