<div dir="ltr">Caused a -Wreorder warning that I fixed here in r172649.<div><br></div><div style>-eric</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Jan 16, 2013 at 11:32 AM, Aaron Ballman <span dir="ltr"><<a href="mailto:aaron@aaronballman.com" target="_blank">aaron@aaronballman.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: aaronballman<br>
Date: Wed Jan 16 13:32:21 2013<br>
New Revision: 172639<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=172639&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=172639&view=rev</a><br>
Log:<br>
No longer crashing with an assert when __has_include or __has_include_next is used outside of a preprocessor directive.  This fixes PR14837.<br>
<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td<br>
    cfe/trunk/include/clang/Lex/Preprocessor.h<br>
    cfe/trunk/lib/Lex/PPDirectives.cpp<br>
    cfe/trunk/lib/Lex/PPMacroExpansion.cpp<br>
    cfe/trunk/lib/Lex/Preprocessor.cpp<br>
    cfe/trunk/test/Preprocessor/has_include.c<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=172639&r1=172638&r2=172639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=172639&r1=172638&r2=172639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Wed Jan 16 13:32:21 2013<br>
@@ -285,6 +285,8 @@<br>
 def note_macro_here : Note<"macro %0 defined here">;<br>
<br>
 def err_pp_invalid_directive : Error<"invalid preprocessing directive">;<br>
+def err_pp_directive_required : Error<<br>
+  "%0 must be used within a preprocessing directive">;<br>
 def err_pp_file_not_found : Error<"'%0' file not found">, DefaultFatal;<br>
 def err_pp_file_not_found_not_fatal : Error<<br>
   "'%0' file not found with <angled> include; use \"quotes\" instead">;<br>
<br>
Modified: cfe/trunk/include/clang/Lex/Preprocessor.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=172639&r1=172638&r2=172639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=172639&r1=172638&r2=172639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)<br>
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Wed Jan 16 13:32:21 2013<br>
@@ -160,6 +160,9 @@<br>
   /// \brief True if pragmas are enabled.<br>
   bool PragmasEnabled : 1;<br>
<br>
+  /// \brief True if we are currently preprocessing a #if or #elif directive<br>
+  bool ParsingIfOrElifDirective;<br>
+<br>
   /// \brief True if we are pre-expanding macro arguments.<br>
   bool InMacroArgPreExpansion;<br>
<br>
@@ -446,6 +449,11 @@<br>
   /// \brief Retrieve the module loader associated with this preprocessor.<br>
   ModuleLoader &getModuleLoader() const { return TheModuleLoader; }<br>
<br>
+  /// \brief True if we are currently preprocessing a #if or #elif directive<br>
+  bool isParsingIfOrElifDirective() const {<br>
+    return ParsingIfOrElifDirective;<br>
+  }<br>
+<br>
   /// SetCommentRetentionState - Control whether or not the preprocessor retains<br>
   /// comments in output.<br>
   void SetCommentRetentionState(bool KeepComments, bool KeepMacroComments) {<br>
<br>
Modified: cfe/trunk/lib/Lex/PPDirectives.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=172639&r1=172638&r2=172639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=172639&r1=172638&r2=172639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)<br>
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Wed Jan 16 13:32:21 2013<br>
@@ -24,6 +24,7 @@<br>
 #include "clang/Lex/Pragma.h"<br>
 #include "llvm/ADT/APInt.h"<br>
 #include "llvm/Support/ErrorHandling.h"<br>
+#include "llvm/Support/SaveAndRestore.h"<br>
 using namespace clang;<br>
<br>
 //===----------------------------------------------------------------------===//<br>
@@ -2071,6 +2072,7 @@<br>
 ///<br>
 void Preprocessor::HandleIfDirective(Token &IfToken,<br>
                                      bool ReadAnyTokensBeforeDirective) {<br>
+  SaveAndRestore<bool> PPDir(ParsingIfOrElifDirective, true);<br>
   ++NumIf;<br>
<br>
   // Parse and evaluate the conditional expression.<br>
@@ -2162,6 +2164,7 @@<br>
 /// HandleElifDirective - Implements the \#elif directive.<br>
 ///<br>
 void Preprocessor::HandleElifDirective(Token &ElifToken) {<br>
+  SaveAndRestore<bool> PPDir(ParsingIfOrElifDirective, true);<br>
   ++NumElse;<br>
<br>
   // #elif directive in a non-skipping conditional... start skipping.<br>
<br>
Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=172639&r1=172638&r2=172639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=172639&r1=172638&r2=172639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)<br>
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Wed Jan 16 13:32:21 2013<br>
@@ -964,6 +964,12 @@<br>
   // that location.  If not, use the end of this location instead.<br>
   SourceLocation LParenLoc = Tok.getLocation();<br>
<br>
+  // These expressions are only allowed within a preprocessor directive.<br>
+  if (!PP.isParsingIfOrElifDirective()) {<br>
+    PP.Diag(LParenLoc, diag::err_pp_directive_required) << II->getName();<br>
+    return false;<br>
+  }<br>
+<br>
   // Get '('.<br>
   PP.LexNonComment(Tok);<br>
<br>
<br>
Modified: cfe/trunk/lib/Lex/Preprocessor.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=172639&r1=172638&r2=172639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=172639&r1=172638&r2=172639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Lex/Preprocessor.cpp (original)<br>
+++ cfe/trunk/lib/Lex/Preprocessor.cpp Wed Jan 16 13:32:21 2013<br>
@@ -69,7 +69,8 @@<br>
     CodeCompletionFile(0), CodeCompletionOffset(0), CodeCompletionReached(0),<br>
     SkipMainFilePreamble(0, true), CurPPLexer(0),<br>
     CurDirLookup(0), CurLexerKind(CLK_Lexer), Callbacks(0), Listener(0),<br>
-    MacroArgCache(0), Record(0), MIChainHead(0), MICache(0)<br>
+    MacroArgCache(0), Record(0), MIChainHead(0), MICache(0),<br>
+    ParsingIfOrElifDirective(false)<br>
 {<br>
   OwnsHeaderSearch = OwnsHeaders;<br>
<br>
<br>
Modified: cfe/trunk/test/Preprocessor/has_include.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/has_include.c?rev=172639&r1=172638&r2=172639&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/has_include.c?rev=172639&r1=172638&r2=172639&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/Preprocessor/has_include.c (original)<br>
+++ cfe/trunk/test/Preprocessor/has_include.c Wed Jan 16 13:32:21 2013<br>
@@ -91,6 +91,28 @@<br>
   #error "__has_include with macro failed (2)."<br>
 #endif<br>
<br>
+// Try as non-preprocessor directives<br>
+void foo( void ) {<br>
+  __has_include_next("stdint.h")  // expected-warning {{#include_next in primary source file}} expected-error {{__has_include_next must be used within a preprocessing directive}}<br>
+  __has_include("stdint.h")  // expected-error {{__has_include must be used within a preprocessing directive}}<br>
+}<br>
+<br>
+MACRO1  // expected-error {{__has_include must be used within a preprocessing directive}}<br>
+<br>
+#if 1<br>
+MACRO1  // expected-error {{__has_include must be used within a preprocessing directive}}<br>
+#endif<br>
+<br>
+#if 0<br>
+#elif 1<br>
+MACRO1  // expected-error {{__has_include must be used within a preprocessing directive}}<br>
+#endif<br>
+<br>
+#if 0<br>
+MACRO1  // This should be fine because it is never actually reached<br>
+#endif<br>
+<br>
+<br>
 // Try badly formed expressions.<br>
 // FIXME: We can recover better in almost all of these cases. (PR13335)<br>
<br>
@@ -126,7 +148,7 @@<br>
 #if __has_include(stdint.h>)<br>
 #endif<br>
<br>
-// expected-error@+1 {{missing '(' after '__has_include'}}<br>
+// expected-error@+1 {{__has_include must be used within a preprocessing directive}}<br>
 __has_include<br>
<br>
 // expected-error@+1 {{missing ')' after '__has_include'}} // expected-error@+1 {{expected value in expression}}  // expected-note@+1 {{to match this '('}}<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>