<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>