[clang] 00dad9d - Ignore noderef attribute in unevaluated context
Aaron Ballman via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 23 05:11:06 PST 2020
Author: Jann Horn
Date: 2020-11-23T08:10:35-05:00
New Revision: 00dad9d028ce31739b992a3ce2df5de054a9fa3c
URL: https://github.com/llvm/llvm-project/commit/00dad9d028ce31739b992a3ce2df5de054a9fa3c
DIFF: https://github.com/llvm/llvm-project/commit/00dad9d028ce31739b992a3ce2df5de054a9fa3c.diff
LOG: 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.
Added:
Modified:
clang/lib/Sema/SemaExpr.cpp
clang/lib/Sema/SemaExprMember.cpp
clang/test/Frontend/noderef.c
clang/test/Frontend/noderef.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 60a685bfdf15..5580cdf13691 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -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.
diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp
index 93ed756e084b..23cfae81df46 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -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
diff --git a/clang/test/Frontend/noderef.c b/clang/test/Frontend/noderef.c
index b072b995fcf6..3388f2a39992 100644
--- a/clang/test/Frontend/noderef.c
+++ b/clang/test/Frontend/noderef.c
@@ -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
diff --git a/clang/test/Frontend/noderef.cpp b/clang/test/Frontend/noderef.cpp
index 32d5ca34d1b1..68342a8e6467 100644
--- a/clang/test/Frontend/noderef.cpp
+++ b/clang/test/Frontend/noderef.cpp
@@ -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;
More information about the cfe-commits
mailing list