<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jul 5, 2017, at 1:33 PM, Aaron Ballman <<a href="mailto:aaron@aaronballman.com" class="">aaron@aaronballman.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">On Wed, Jul 5, 2017 at 4:20 PM, Douglas Gregor via cfe-commits</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class=""><</span><a href="mailto:cfe-commits@lists.llvm.org" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">cfe-commits@lists.llvm.org</a><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">> wrote:</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">Author: dgregor<br class="">Date: Wed Jul  5 13:20:15 2017<br class="">New Revision: 307197<br class=""><br class="">URL: <a href="http://llvm.org/viewvc/llvm-project?rev=307197&view=rev" class="">http://llvm.org/viewvc/llvm-project?rev=307197&view=rev</a><br class="">Log:<br class="">Cope with Range-v3's CONCEPT_REQUIRES idiom<br class=""><br class="">Modified:<br class="">   cfe/trunk/lib/Sema/SemaTemplate.cpp<br class="">   cfe/trunk/test/SemaTemplate/overload-candidates.cpp<br class=""><br class="">Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=307197&r1=307196&r2=307197&view=diff" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=307197&r1=307196&r2=307197&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)<br class="">+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Jul  5 13:20:15 2017<br class="">@@ -2831,10 +2831,44 @@ static void collectConjunctionTerms(Expr<br class="">  Terms.push_back(Clause);<br class="">}<br class=""><br class="">+// The ranges-v3 library uses an odd pattern of a top-level "||" with<br class="">+// a left-hand side that is value-dependent but never true. Identify<br class="">+// the idiom and ignore that term.<br class="">+static Expr *lookThroughRangesV3Condition(Preprocessor &PP, Expr *Cond) {<br class="">+  // Top-level '||'.<br class="">+  auto *BinOp = dyn_cast<BinaryOperator>(Cond->IgnoreParenImpCasts());<br class="">+  if (!BinOp) return Cond;<br class="">+<br class="">+  if (BinOp->getOpcode() != BO_LOr) return Cond;<br class="">+<br class="">+  // With an inner '==' that has a literal on the right-hand side.<br class="">+  Expr *LHS = BinOp->getLHS();<br class="">+  auto InnerBinOp = dyn_cast<BinaryOperator>(LHS->IgnoreParenImpCasts());<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">auto * please (or better yet, const auto * here and above).</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></blockquote><div><br class=""></div>Sure, commit incoming.</div><div><br class=""><blockquote type="cite" class=""><div class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">+  if (!InnerBinOp) return Cond;<br class="">+<br class="">+  if (InnerBinOp->getOpcode() != BO_EQ ||<br class="">+      !isa<IntegerLiteral>(InnerBinOp->getRHS()))<br class="">+    return Cond;<br class="">+<br class="">+  // If the inner binary operation came from a macro expansion named<br class="">+  // CONCEPT_REQUIRES or CONCEPT_REQUIRES_, return the right-hand side<br class="">+  // of the '||', which is the real, user-provided condition.<br class="">+  auto Loc = InnerBinOp->getExprLoc();<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Please do not use auto here.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></blockquote><div><br class=""></div>I’m fine with spelling it out, although I don’t know what criteria you’re applying here. Presumably it’s okay to use “auto” when the initializer is some form of cast to that type, but you prefer not to use “auto” elsewhere, despite the “Loc” in the variable name and in the initializer?</div><div><br class=""><blockquote type="cite" class=""><div class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">It's unfortunate that we have this special case instead of a more</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">general mechanism. While I love Ranges v3, I'm not keen on a compiler</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">hack just for it. These "tricks" have a habit of leaking out into</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">other user code, which will behave differently than what happens with</span></div></blockquote><blockquote type="cite" class=""><div class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Ranges.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></blockquote><div><br class=""></div><div>It’s possible that we can do something more general here by converting the expression to disjunctive normal form and identifying when some of the top-level terms will never succeed. </div><div><br class=""></div><span class="Apple-tab-span" style="white-space:pre">        </span>- Doug</div><div><br class=""><blockquote type="cite" class=""><div class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">~Aaron</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">+  if (!Loc.isMacroID()) return Cond;<br class="">+<br class="">+  StringRef MacroName = PP.getImmediateMacroName(Loc);<br class="">+  if (MacroName == "CONCEPT_REQUIRES" || MacroName == "CONCEPT_REQUIRES_")<br class="">+    return BinOp->getRHS();<br class="">+<br class="">+  return Cond;<br class="">+}<br class="">+<br class="">/// Find the failed subexpression within enable_if, and describe it<br class="">/// with a string.<br class="">static std::pair<Expr *, std::string><br class="">findFailedEnableIfCondition(Sema &S, Expr *Cond) {<br class="">+  Cond = lookThroughRangesV3Condition(S.PP, Cond);<br class="">+<br class="">  // Separate out all of the terms in a conjunction.<br class="">  SmallVector<Expr *, 4> Terms;<br class="">  collectConjunctionTerms(Cond, Terms);<br class=""><br class="">Modified: cfe/trunk/test/SemaTemplate/overload-candidates.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/overload-candidates.cpp?rev=307197&r1=307196&r2=307197&view=diff" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/overload-candidates.cpp?rev=307197&r1=307196&r2=307197&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/test/SemaTemplate/overload-candidates.cpp (original)<br class="">+++ cfe/trunk/test/SemaTemplate/overload-candidates.cpp Wed Jul  5 13:20:15 2017<br class="">@@ -137,4 +137,30 @@ namespace PR15673 {<br class="">#endif<br class="">  void wibble() {}<br class="">  void wobble() { wibble<int>(); } // expected-error {{no matching function for call to 'wibble'}}<br class="">+<br class="">+  template<typename T><br class="">+  struct some_passing_trait : std::true_type {};<br class="">+<br class="">+#if __cplusplus <= 199711L<br class="">+  // expected-warning@+4 {{default template arguments for a function template are a C++11 extension}}<br class="">+  // expected-warning@+4 {{default template arguments for a function template are a C++11 extension}}<br class="">+#endif<br class="">+  template<typename T,<br class="">+           int n = 42,<br class="">+           typename std::enable_if<n == 43 || (some_passing_trait<T>::value && some_trait<T>::value), int>::type = 0><br class="">+  void almost_rangesv3(); // expected-note{{candidate template ignored: requirement '42 == 43 || (some_passing_trait<int>::value && some_trait<int>::value)' was not satisfied}}<br class="">+  void test_almost_rangesv3() { almost_rangesv3<int>(); } // expected-error{{no matching function for call to 'almost_rangesv3'}}<br class="">+<br class="">+  #define CONCEPT_REQUIRES_(...)                                        \<br class="">+    int x = 42,                                                         \<br class="">+    typename std::enable_if<(x == 43) || (__VA_ARGS__)>::type = 0<br class="">+<br class="">+#if __cplusplus <= 199711L<br class="">+  // expected-warning@+4 {{default template arguments for a function template are a C++11 extension}}<br class="">+  // expected-warning@+4 {{default template arguments for a function template are a C++11 extension}}<br class="">+#endif<br class="">+  template<typename T,<br class="">+           CONCEPT_REQUIRES_(some_passing_trait<T>::value && some_trait<T>::value)><br class="">+  void rangesv3(); // expected-note{{candidate template ignored: requirement 'some_trait<int>::value' was not satisfied [with T = int, x = 42]}}<br class="">+  void test_rangesv3() { rangesv3<int>(); } // expected-error{{no matching function for call to 'rangesv3'}}<br class="">}<br class=""><br class=""><br class="">_______________________________________________<br class="">cfe-commits mailing list<br class=""><a href="mailto:cfe-commits@lists.llvm.org" class="">cfe-commits@lists.llvm.org</a><br class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</blockquote></div></blockquote></div><br class=""></body></html>