<div dir="ltr">This seems to break check-clang-tools on non-Linux:<div><a href="http://45.33.8.238/mac/6529/step_8.txt">http://45.33.8.238/mac/6529/step_8.txt</a><br></div><div><a href="http://45.33.8.238/win/6770/step_8.txt">http://45.33.8.238/win/6770/step_8.txt</a><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Jan 27, 2020 at 9:21 PM Richard Smith via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
Author: Richard Smith<br>
Date: 2020-01-27T18:20:57-08:00<br>
New Revision: af80b8ccc5772c14920d4554b7ca7e15f2fad1c4<br>
<br>
URL: <a href="https://github.com/llvm/llvm-project/commit/af80b8ccc5772c14920d4554b7ca7e15f2fad1c4" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/af80b8ccc5772c14920d4554b7ca7e15f2fad1c4</a><br>
DIFF: <a href="https://github.com/llvm/llvm-project/commit/af80b8ccc5772c14920d4554b7ca7e15f2fad1c4.diff" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/af80b8ccc5772c14920d4554b7ca7e15f2fad1c4.diff</a><br>
<br>
LOG: PR44684: Look through parens and similar constructs when determining<br>
whether a call is to a builtin.<br>
<br>
We already had a general mechanism to do this but for some reason<br>
weren't using it. In passing, check for the other unary operators that<br>
can intervene in a reasonably-direct function call (we already handled<br>
'&' but missed '*' and '+').<br>
<br>
Added: <br>
<br>
<br>
Modified: <br>
    clang/lib/AST/Expr.cpp<br>
    clang/lib/AST/ExprConstant.cpp<br>
    clang/test/Parser/builtin_classify_type.c<br>
    clang/test/Sema/constant-builtins.c<br>
<br>
Removed: <br>
<br>
<br>
<br>
################################################################################<br>
diff  --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp<br>
index 20505b21b15c..c2f73c2dc9d5 100644<br>
--- a/clang/lib/AST/Expr.cpp<br>
+++ b/clang/lib/AST/Expr.cpp<br>
@@ -1443,19 +1443,28 @@ void CallExpr::updateDependenciesFromArg(Expr *Arg) {<br>
 Decl *Expr::getReferencedDeclOfCallee() {<br>
   Expr *CEE = IgnoreParenImpCasts();<br>
<br>
-  while (SubstNonTypeTemplateParmExpr *NTTP<br>
-                                = dyn_cast<SubstNonTypeTemplateParmExpr>(CEE)) {<br>
-    CEE = NTTP->getReplacement()->IgnoreParenCasts();<br>
+  while (SubstNonTypeTemplateParmExpr *NTTP =<br>
+             dyn_cast<SubstNonTypeTemplateParmExpr>(CEE)) {<br>
+    CEE = NTTP->getReplacement()->IgnoreParenImpCasts();<br>
   }<br>
<br>
   // If we're calling a dereference, look at the pointer instead.<br>
-  if (BinaryOperator *BO = dyn_cast<BinaryOperator>(CEE)) {<br>
-    if (BO->isPtrMemOp())<br>
-      CEE = BO->getRHS()->IgnoreParenCasts();<br>
-  } else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(CEE)) {<br>
-    if (UO->getOpcode() == UO_Deref)<br>
-      CEE = UO->getSubExpr()->IgnoreParenCasts();<br>
+  while (true) {<br>
+    if (BinaryOperator *BO = dyn_cast<BinaryOperator>(CEE)) {<br>
+      if (BO->isPtrMemOp()) {<br>
+        CEE = BO->getRHS()->IgnoreParenImpCasts();<br>
+        continue;<br>
+      }<br>
+    } else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(CEE)) {<br>
+      if (UO->getOpcode() == UO_Deref || UO->getOpcode() == UO_AddrOf ||<br>
+          UO->getOpcode() == UO_Plus) {<br>
+        CEE = UO->getSubExpr()->IgnoreParenImpCasts();<br>
+        continue;<br>
+      }<br>
+    }<br>
+    break;<br>
   }<br>
+<br>
   if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE))<br>
     return DRE->getDecl();<br>
   if (MemberExpr *ME = dyn_cast<MemberExpr>(CEE))<br>
@@ -1466,28 +1475,11 @@ Decl *Expr::getReferencedDeclOfCallee() {<br>
   return nullptr;<br>
 }<br>
<br>
-/// getBuiltinCallee - If this is a call to a builtin, return the builtin ID. If<br>
-/// not, return 0.<br>
+/// If this is a call to a builtin, return the builtin ID. If not, return 0.<br>
 unsigned CallExpr::getBuiltinCallee() const {<br>
-  // All simple function calls (e.g. func()) are implicitly cast to pointer to<br>
-  // function. As a result, we try and obtain the DeclRefExpr from the<br>
-  // ImplicitCastExpr.<br>
-  const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(getCallee());<br>
-  if (!ICE) // FIXME: deal with more complex calls (e.g. (func)(), (*func)()).<br>
-    return 0;<br>
-<br>
-  const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr());<br>
-  if (!DRE)<br>
-    return 0;<br>
-<br>
-  const FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());<br>
-  if (!FDecl)<br>
-    return 0;<br>
-<br>
-  if (!FDecl->getIdentifier())<br>
-    return 0;<br>
-<br>
-  return FDecl->getBuiltinID();<br>
+  auto *FDecl =<br>
+      dyn_cast_or_null<FunctionDecl>(getCallee()->getReferencedDeclOfCallee());<br>
+  return FDecl ? FDecl->getBuiltinID() : 0;<br>
 }<br>
<br>
 bool CallExpr::isUnevaluatedBuiltinCall(const ASTContext &Ctx) const {<br>
<br>
diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp<br>
index c79973507323..75554c4692e9 100644<br>
--- a/clang/lib/AST/ExprConstant.cpp<br>
+++ b/clang/lib/AST/ExprConstant.cpp<br>
@@ -10660,7 +10660,7 @@ static bool getBuiltinAlignArguments(const CallExpr *E, EvalInfo &Info,<br>
<br>
 bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,<br>
                                             unsigned BuiltinOp) {<br>
-  switch (unsigned BuiltinOp = E->getBuiltinCallee()) {<br>
+  switch (BuiltinOp) {<br>
   default:<br>
     return ExprEvaluatorBaseTy::VisitCallExpr(E);<br>
<br>
<br>
diff  --git a/clang/test/Parser/builtin_classify_type.c b/clang/test/Parser/builtin_classify_type.c<br>
index 63fd8e28045a..94434e9f2ee4 100644<br>
--- a/clang/test/Parser/builtin_classify_type.c<br>
+++ b/clang/test/Parser/builtin_classify_type.c<br>
@@ -9,7 +9,7 @@ int main() {<br>
   struct foo s;<br>
<br>
   static int ary[__builtin_classify_type(a)];<br>
-  static int ary2[(__builtin_classify_type)(a)]; // expected-error{{variable length array declaration cannot have 'static' storage duration}}<br>
+  static int ary2[(__builtin_classify_type)(a)];<br>
   static int ary3[(*__builtin_classify_type)(a)]; // expected-error{{builtin functions must be directly called}}<br>
<br>
   int result;<br>
<br>
diff  --git a/clang/test/Sema/constant-builtins.c b/clang/test/Sema/constant-builtins.c<br>
index c98f62dfc5a2..ae3b9135c965 100644<br>
--- a/clang/test/Sema/constant-builtins.c<br>
+++ b/clang/test/Sema/constant-builtins.c<br>
@@ -25,4 +25,13 @@ short somefunc();<br>
<br>
 short t = __builtin_constant_p(5353) ? 42 : somefunc();<br>
<br>
-<br>
+// PR44684<br>
+_Static_assert((__builtin_clz)(1u) >= 15, "");<br>
+_Static_assert((__builtin_popcount)(1u) == 1, "");<br>
+_Static_assert((__builtin_ctz)(2u) == 1, "");<br>
+_Static_assert(_Generic(1u,unsigned:__builtin_clz)(1u) >= 15, "");<br>
+_Static_assert(_Generic(1u,unsigned:__builtin_popcount)(1u) == 1, "");<br>
+_Static_assert(_Generic(1u,unsigned:__builtin_ctz)(2u) == 1, "");<br>
+<br>
+__SIZE_TYPE__ strlen(const char*);<br>
+_Static_assert((__builtin_constant_p(1) ? (***&strlen)("foo") : 0) == 3, "");<br>
<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div>