Skip to content

Commit 7bcc210

Browse files
committedMay 14, 2018
[AST] Fix -ast-print for _Bool when have diagnostics
For example, given: #define bool _Bool _Bool i; void fn() { 1; } -ast-print produced: tmp.c:3:13: warning: expression result unused void fn() { 1; } ^ bool i; void fn() { 1; } That fails to compile because bool is undefined. Details: Diagnostics print _Bool as bool when the latter is defined as the former. However, diagnostics were altering the printing policy for -ast-print as well. The printed source was then invalid because the preprocessor eats the bool definition. Problematic diagnostics included suppressed warnings (e.g., add -Wno-unused-value to the above example), including those that are suppressed by default. This patch fixes this bug and cleans up some related comments. Reviewed by: aaron.ballman, rsmith Differential Revision: https://reviews.llvm.org/D45093 llvm-svn: 332275
1 parent 215ce4a commit 7bcc210

File tree

4 files changed

+54
-8
lines changed

4 files changed

+54
-8
lines changed
 

‎clang/include/clang/Sema/Sema.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2113,12 +2113,12 @@ class Sema {
21132113
void checkPartialSpecializationVisibility(SourceLocation Loc,
21142114
NamedDecl *Spec);
21152115

2116-
/// Retrieve a suitable printing policy.
2116+
/// Retrieve a suitable printing policy for diagnostics.
21172117
PrintingPolicy getPrintingPolicy() const {
21182118
return getPrintingPolicy(Context, PP);
21192119
}
21202120

2121-
/// Retrieve a suitable printing policy.
2121+
/// Retrieve a suitable printing policy for diagnostics.
21222122
static PrintingPolicy getPrintingPolicy(const ASTContext &Ctx,
21232123
const Preprocessor &PP);
21242124

‎clang/lib/Frontend/ASTConsumers.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,10 @@ namespace {
8787
<< DC->getPrimaryContext() << "\n";
8888
} else
8989
Out << "Not a DeclContext\n";
90-
} else if (OutputKind == Print)
91-
D->print(Out, /*Indentation=*/0, /*PrintInstantiation=*/true);
92-
else if (OutputKind != None)
90+
} else if (OutputKind == Print) {
91+
PrintingPolicy Policy(D->getASTContext().getLangOpts());
92+
D->print(Out, Policy, /*Indentation=*/0, /*PrintInstantiation=*/true);
93+
} else if (OutputKind != None)
9394
D->dump(Out, OutputKind == DumpFull);
9495
}
9596

‎clang/lib/Sema/Sema.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ ModuleLoader &Sema::getModuleLoader() const { return PP.getModuleLoader(); }
5252
PrintingPolicy Sema::getPrintingPolicy(const ASTContext &Context,
5353
const Preprocessor &PP) {
5454
PrintingPolicy Policy = Context.getPrintingPolicy();
55-
// Our printing policy is copied over the ASTContext printing policy whenever
56-
// a diagnostic is emitted, so recompute it.
55+
// In diagnostics, we print _Bool as bool if the latter is defined as the
56+
// former.
5757
Policy.Bool = Context.getLangOpts().Bool;
5858
if (!Policy.Bool) {
5959
if (const MacroInfo *BoolMacro = PP.getMacroInfo(Context.getBoolName())) {
@@ -1287,7 +1287,8 @@ void Sema::EmitCurrentDiagnostic(unsigned DiagID) {
12871287
}
12881288
}
12891289

1290-
// Set up the context's printing policy based on our current state.
1290+
// Copy the diagnostic printing policy over the ASTContext printing policy.
1291+
// TODO: Stop doing that. See: https://reviews.llvm.org/D45093#1090292
12911292
Context.setPrintingPolicy(getPrintingPolicy());
12921293

12931294
// Emit the diagnostic.

‎clang/test/Misc/ast-print-bool.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// RUN: %clang_cc1 -verify -ast-print %s -xc -DDEF_BOOL_CBOOL \
2+
// RUN: | FileCheck %s --check-prefixes=BOOL-AS-CBOOL,CBOOL
3+
//
4+
// RUN: %clang_cc1 -verify -ast-print %s -xc -DDEF_BOOL_CBOOL -DDIAG \
5+
// RUN: | FileCheck %s --check-prefixes=BOOL-AS-CBOOL,CBOOL
6+
//
7+
// RUN: %clang_cc1 -verify -ast-print %s -xc -DDEF_BOOL_INT \
8+
// RUN: | FileCheck %s --check-prefixes=BOOL-AS-INT,CBOOL
9+
//
10+
// RUN: %clang_cc1 -verify -ast-print %s -xc -DDEF_BOOL_INT -DDIAG \
11+
// RUN: | FileCheck %s --check-prefixes=BOOL-AS-INT,CBOOL
12+
//
13+
// RUN: %clang_cc1 -verify -ast-print %s -xc++ \
14+
// RUN: | FileCheck %s --check-prefixes=BOOL-AS-BOOL
15+
//
16+
// RUN: %clang_cc1 -verify -ast-print %s -xc++ -DDIAG \
17+
// RUN: | FileCheck %s --check-prefixes=BOOL-AS-BOOL
18+
19+
#if DEF_BOOL_CBOOL
20+
# define bool _Bool
21+
#elif DEF_BOOL_INT
22+
# define bool int
23+
#endif
24+
25+
// BOOL-AS-CBOOL: _Bool i;
26+
// BOOL-AS-INT: int i;
27+
// BOOL-AS-BOOL: bool i;
28+
bool i;
29+
30+
#ifndef __cplusplus
31+
// CBOOL: _Bool j;
32+
_Bool j;
33+
#endif
34+
35+
// Induce a diagnostic (and verify we actually managed to do so), which used to
36+
// permanently alter the -ast-print printing policy for _Bool. How bool is
37+
// defined by the preprocessor is examined only once per compilation, when the
38+
// diagnostic is emitted, and it used to affect the entirety of -ast-print, so
39+
// test only one definition of bool per compilation.
40+
#if DIAG
41+
void fn() { 1; } // expected-warning {{expression result unused}}
42+
#else
43+
// expected-no-diagnostics
44+
#endif

0 commit comments

Comments
 (0)
Please sign in to comment.