forked from OSchip/llvm-project
Ignore noderef attribute in unevaluated context
The noderef attribute is for catching code that accesses pointers in a different address space. Unevaluated code is always safe in that regard.
This commit is contained in:
parent
1ec60862d7
commit
00dad9d028
|
@ -4751,6 +4751,9 @@ void Sema::CheckAddressOfNoDeref(const Expr *E) {
|
|||
}
|
||||
|
||||
void Sema::CheckSubscriptAccessOfNoDeref(const ArraySubscriptExpr *E) {
|
||||
if (isUnevaluatedContext())
|
||||
return;
|
||||
|
||||
QualType ResultTy = E->getType();
|
||||
ExpressionEvaluationContextRecord &LastRecord = ExprEvalContexts.back();
|
||||
|
||||
|
@ -14666,7 +14669,8 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
|
|||
OpLoc, CanOverflow, CurFPFeatureOverrides());
|
||||
|
||||
if (Opc == UO_Deref && UO->getType()->hasAttr(attr::NoDeref) &&
|
||||
!isa<ArrayType>(UO->getType().getDesugaredType(Context)))
|
||||
!isa<ArrayType>(UO->getType().getDesugaredType(Context)) &&
|
||||
!isUnevaluatedContext())
|
||||
ExprEvalContexts.back().PossibleDerefs.insert(UO);
|
||||
|
||||
// Convert the result back to a half vector.
|
||||
|
|
|
@ -1734,6 +1734,9 @@ ExprResult Sema::ActOnMemberAccessExpr(Scope *S, Expr *Base,
|
|||
}
|
||||
|
||||
void Sema::CheckMemberAccessOfNoDeref(const MemberExpr *E) {
|
||||
if (isUnevaluatedContext())
|
||||
return;
|
||||
|
||||
QualType ResultTy = E->getType();
|
||||
|
||||
// Do not warn on member accesses to arrays since this returns an array
|
||||
|
|
|
@ -57,12 +57,19 @@ int test() {
|
|||
p = &*(p + 1);
|
||||
|
||||
// Struct member access
|
||||
struct S NODEREF *s; // expected-note 2 {{s declared here}}
|
||||
struct S NODEREF *s; // expected-note 3 {{s declared here}}
|
||||
x = s->a; // expected-warning{{dereferencing s; was declared with a 'noderef' type}}
|
||||
x = (*s).b; // expected-warning{{dereferencing s; was declared with a 'noderef' type}}
|
||||
p = &s->a;
|
||||
p = &(*s).b;
|
||||
|
||||
// Most things in sizeof() can't actually access memory
|
||||
x = sizeof(s->a); // ok
|
||||
x = sizeof(*s); // ok
|
||||
x = sizeof(s[0]); // ok
|
||||
x = sizeof(s->a + (s->b)); // ok
|
||||
x = sizeof(int[++s->a]); // expected-warning{{dereferencing s; was declared with a 'noderef' type}}
|
||||
|
||||
// Nested struct access
|
||||
struct S2 NODEREF *s2_noderef; // expected-note 5 {{s2_noderef declared here}}
|
||||
p = s2_noderef->a; // ok since result is an array in a struct
|
||||
|
|
|
@ -6,6 +6,11 @@
|
|||
|
||||
#define NODEREF __attribute__((noderef))
|
||||
|
||||
// Stub out types for 'typeid' to work.
|
||||
namespace std {
|
||||
class type_info {};
|
||||
} // namespace std
|
||||
|
||||
void Normal() {
|
||||
int NODEREF i; // expected-warning{{'noderef' can only be used on an array or pointer type}}
|
||||
int NODEREF *i_ptr; // expected-note 2 {{i_ptr declared here}}
|
||||
|
@ -102,6 +107,18 @@ int ChildCall(NODEREF Child *child) { // expected-note{{child declared here}}
|
|||
return child->func(); // expected-warning{{dereferencing child; was declared with a 'noderef' type}}
|
||||
}
|
||||
|
||||
std::type_info TypeIdPolymorphic(NODEREF A *a) { // expected-note{{a declared here}}
|
||||
return typeid(*a); // expected-warning{{dereferencing a; was declared with a 'noderef' type}}
|
||||
}
|
||||
|
||||
class SimpleClass {
|
||||
int a;
|
||||
};
|
||||
|
||||
std::type_info TypeIdNonPolymorphic(NODEREF SimpleClass *simple) {
|
||||
return typeid(*simple);
|
||||
}
|
||||
|
||||
template <class Ty>
|
||||
class B {
|
||||
Ty NODEREF *member;
|
||||
|
|
Loading…
Reference in New Issue