rsmith added a comment.

In https://reviews.llvm.org/D49511#1170693, @leonardchan wrote:

> Done. I opted for not using `ExpressionEvaluationContextRecord` because I 
> don't think I was using it correctly. A few other tests in sema failed when I 
> tried pushing and popping from the stack holding these. I still process 
> expressions as they are parsed though without using AST traversal on every 
> expression.


You shouldn't be adding your own `ExpressionEvaluationContextRecord`s. What I 
was suggesting is that you store a list of pending `noderef` expressions on the 
record, and diagnose them when the record is popped (if they've not been 
removed since). Your current counter-based approach doesn't work very well in 
the case where we switch to another context while processing an expression (for 
example, during template instantiation): you'll defer all the diagnostics for 
the inner construct until the outer construct is complete. Generally global 
`Sema` state doesn't work very well for this reason.

That said... have you considered changing the specification of your attribute 
so that you warn on lvalue-to-rvalue conversions instead of warning on 
dereference-like things with a list of exceptions? That would be both simpler 
to implement and more precise (and it would naturally extend to C++, where a 
reference-to-`noderef` would be a reasonable type to support).



================
Comment at: include/clang/Sema/Sema.h:1556
+  unsigned NoDerefCallCount = 0;
+  std::unordered_set<const Expr *> PossibleDerefs;
+
----------------
Do not use `unordered_set` here; see 
https://llvm.org/docs/ProgrammersManual.html#picking-the-right-data-structure-for-a-task

`llvm::SmallPtrSet` or `llvm::DenseSet` would be better choices here, but I 
think just using a `SmallVector` would be fine. 


================
Comment at: lib/Sema/SemaExpr.cpp:14230-14242
+class DeclRefFinder : public ConstEvaluatedExprVisitor<DeclRefFinder> {
+public:
+  typedef ConstEvaluatedExprVisitor<DeclRefFinder> Inherited;
+
+  DeclRefFinder(ASTContext &Ctx) : Inherited(Ctx) {}
+
+  void VisitDeclRefExpr(const DeclRefExpr *E) { DeclRef = E; }
----------------
I don't see any reason to assume that the `DeclRefExpr` found by this visitor 
will be the one you're interested in (the one the `noderef` attribute came 
from).

How about instead you walk over only expressions that you *know* preserve 
`noderef`, and if you can't find a declaration as the source of the `noderef` 
attribute, produce a differently-worded diagnostic that doesn't give a variable 
name?


================
Comment at: lib/Sema/SemaExpr.cpp:14252-14257
+      const DeclRefExpr *DeclRef = Finder.GetDeclRef();
+      const ValueDecl *Decl = DeclRef->getDecl();
+
+      Diag(E->getExprLoc(), diag::warn_dereference_of_noderef_type)
+          << Decl->getName() << E->getSourceRange();
+      Diag(Decl->getLocation(), diag::note_previous_decl) << Decl->getName();
----------------
This will crash if the `DeclRefFinder` doesn't find a `DeclRefExpr`. What 
justifies the assumption that it will always succeed?


Repository:
  rC Clang

https://reviews.llvm.org/D49511



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to