src
warn.cc
Go to the documentation of this file.
1 #include <stddef.h>
2 #include <stdio.h>
3 #include <algorithm>
4 #include <utility>
5 
6 #include "src/conf/msg.h"
7 #include "src/conf/warn.h"
8 
9 namespace re2c {
10 
12 
13 const uint32_t Warn::SILENT = 0;
14 const uint32_t Warn::WARNING = 1u << 0;
15 const uint32_t Warn::ERROR = 1u << 1;
16 
17 const char * Warn::names [TYPES] =
18 {
19 #define W(x, y) y
21 #undef W
22 };
23 
25  : mask ()
26  , error_accuml (false)
27 {
28  for (uint32_t i = 0; i < TYPES; ++i)
29  {
30  mask[i] = SILENT;
31  }
32 }
33 
34 bool Warn::error () const
35 {
36  return error_accuml;
37 }
38 
40 {
41  switch (o)
42  {
43  case W:
44  mask[t] |= WARNING;
45  break;
46  case WNO:
47  mask[t] &= ~WARNING;
48  break;
49  case WERROR:
50  // unlike -Werror, -Werror-<warning> implies -W<warning>
51  mask[t] |= (WARNING | ERROR);
52  break;
53  case WNOERROR:
54  mask[t] &= ~ERROR;
55  break;
56  }
57 }
58 
60 {
61  for (uint32_t i = 0; i < TYPES; ++i)
62  {
63  mask[i] |= WARNING;
64  }
65 }
66 
67 // -Werror doesn't set any warnings: it only guarantees that if a warning
68 // has been set by now or will be set later then it will result into error.
70 {
71  for (uint32_t i = 0; i < TYPES; ++i)
72  {
73  mask[i] |= ERROR;
74  }
75 }
76 
77 void Warn::fail (type_t t, uint32_t line, const char * s)
78 {
79  if (mask[t] & WARNING)
80  {
81  // -Werror has no effect
82  warning (names[t], line, false, "%s", s);
83  }
84 }
85 
86 void Warn::condition_order (uint32_t line)
87 {
88  if (mask[CONDITION_ORDER] & WARNING)
89  {
90  const bool e = mask[CONDITION_ORDER] & ERROR;
91  error_accuml |= e;
92  warning (names[CONDITION_ORDER], line, e,
93  "looks like you use hardcoded numbers instead of autogenerated condition names: "
94  "better add '/*!types:re2c*/' directive or '-t, --type-header' option "
95  "and don't rely on fixed condition order.");
96  }
97 }
98 
99 void Warn::empty_class (uint32_t line)
100 {
101  if (mask[EMPTY_CHARACTER_CLASS] & WARNING)
102  {
103  const bool e = mask[EMPTY_CHARACTER_CLASS] & ERROR;
104  error_accuml |= e;
105  warning (names[EMPTY_CHARACTER_CLASS], line, e, "empty character class");
106  }
107 }
108 
109 void Warn::match_empty_string (uint32_t line)
110 {
111  if (mask[MATCH_EMPTY_STRING] & WARNING)
112  {
113  const bool e = mask[MATCH_EMPTY_STRING] & ERROR;
114  error_accuml |= e;
115  warning (names[MATCH_EMPTY_STRING], line, e, "rule matches empty string");
116  }
117 }
118 
119 void Warn::swapped_range (uint32_t line, uint32_t l, uint32_t u)
120 {
121  if (mask[SWAPPED_RANGE] & WARNING)
122  {
123  const bool e = mask[SWAPPED_RANGE] & ERROR;
124  error_accuml |= e;
125  warning (names[SWAPPED_RANGE], line, e, "range lower bound (0x%X) is greater than upper bound (0x%X), swapping", l, u);
126  }
127 }
128 
129 void Warn::undefined_control_flow (uint32_t line, const std::string & cond, std::vector<way_t> & ways, bool overflow)
130 {
131  if (mask[UNDEFINED_CONTROL_FLOW] & WARNING)
132  {
133  const bool e = mask[UNDEFINED_CONTROL_FLOW] & ERROR;
134  error_accuml |= e;
135 
136  // report shorter patterns first
137  std::sort (ways.begin (), ways.end (), cmp_ways);
138 
139  warning_start (line, e);
140  fprintf (stderr, "control flow %sis undefined for strings that match ", incond (cond).c_str ());
141  const size_t count = ways.size ();
142  if (count == 1)
143  {
144  fprint_way (stderr, ways[0]);
145  }
146  else
147  {
148  for (size_t i = 0; i < count; ++i)
149  {
150  fprintf (stderr, "\n\t");
151  fprint_way (stderr, ways[i]);
152  }
153  fprintf (stderr, "\n");
154  }
155  if (overflow)
156  {
157  fprintf (stderr, " ... and a few more");
158  }
159  fprintf (stderr, ", use default rule '*'");
161  }
162 }
163 
164 void Warn::unreachable_rule (const std::string & cond, const rule_info_t & rule, const rules_t & rules)
165 {
166  if (mask[UNREACHABLE_RULES] & WARNING)
167  {
168  const bool e = mask[UNREACHABLE_RULES] & ERROR;
169  error_accuml |= e;
170  warning_start (rule.line, e);
171  fprintf (stderr, "unreachable rule %s", incond (cond).c_str ());
172  const size_t shadows = rule.shadow.size ();
173  if (shadows > 0)
174  {
175  const char * pl = shadows > 1
176  ? "s"
177  : "";
178  std::set<rule_rank_t>::const_iterator i = rule.shadow.begin ();
179  fprintf (stderr, "(shadowed by rule%s at line%s %u", pl, pl, rules.find (*i)->second.line);
180  for (++i; i != rule.shadow.end (); ++i)
181  {
182  fprintf (stderr, ", %u", rules.find (*i)->second.line);
183  }
184  fprintf (stderr, ")");
185  }
186  warning_end (names[UNREACHABLE_RULES], e);
187  }
188 }
189 
190 void Warn::useless_escape (uint32_t line, uint32_t col, char c)
191 {
192  if (mask[USELESS_ESCAPE] & WARNING)
193  {
194  const bool e = mask[USELESS_ESCAPE] & ERROR;
195  error_accuml |= e;
196  warning (names[USELESS_ESCAPE], line, e, "column %u: escape has no effect: '\\%c'", col, c);
197  }
198 }
199 
200 } // namespace re2c
Warn warn
Definition: warn.cc:11
void undefined_control_flow(uint32_t line, const std::string &cond, std::vector< way_t > &ways, bool overflow)
Definition: warn.cc:129
void swapped_range(uint32_t line, uint32_t l, uint32_t u)
Definition: warn.cc:119
std::map< rule_rank_t, rule_info_t > rules_t
Definition: rules.h:25
type_t
Definition: warn.h:25
void warning_start(uint32_t line, bool error)
Definition: msg.cc:32
void set_all()
Definition: warn.cc:59
void set_all_error()
Definition: warn.cc:69
uint32_t line
Definition: rules.h:14
void empty_class(uint32_t line)
Definition: warn.cc:99
void match_empty_string(uint32_t line)
Definition: warn.cc:109
void warning(const char *type, uint32_t line, bool error, const char *fmt,...)
Definition: msg.cc:48
void useless_escape(uint32_t line, uint32_t col, char c)
Definition: warn.cc:190
#define RE2C_WARNING_TYPES
Definition: warn.h:13
void warning_end(const char *type, bool error)
Definition: msg.cc:38
std::set< rule_rank_t > shadow
Definition: rules.h:15
void unreachable_rule(const std::string &cond, const rule_info_t &rule, const rules_t &rules)
Definition: warn.cc:164
option_t
Definition: warn.h:32
void fail(type_t t, uint32_t line, const char *s)
Definition: warn.cc:77
void condition_order(uint32_t line)
Definition: warn.cc:86
Warn()
Definition: warn.cc:24
void fprint_way(FILE *f, const way_t &w)
Definition: way.cc:28
bool error() const
Definition: warn.cc:34
Definition: bitmap.cc:10
bool cmp_ways(const way_t &w1, const way_t &w2)
Definition: way.cc:20
void set(type_t t, option_t o)
Definition: warn.cc:39
std::string incond(const std::string &cond)
Definition: msg.cc:242