[PATCH 06/12] Regularise error reporting

John Levon <[email protected]>
Newsgroups org.kernel.vger.smatch
Message-ID <[email protected]>
The idea is that parse errors and other internal errors are reported back in the
exit code, while still reporting the context where needed.

A user can specify --fatal-checks to make check-level failures do the same.

Signed-off-by: John Levon <[email protected]>
---
 check_kernel_printf.c        |  2 +-
 check_memcpy_overflow.c      |  2 +-
 check_rosenberg.c            |  2 +-
 check_uninitialized.c        | 10 +++----
 check_wrong_size_arg.c       |  2 +-
 smatch.c                     | 31 +++++++++++++++------
 smatch.h                     | 65 ++++++++++++++++++++++++++++++++++++++++++--
 smatch_auto_copy.c           |  2 +-
 smatch_comparison.c          |  6 ++--
 smatch_db.c                  | 28 +++++++++----------
 smatch_flow.c                | 24 +++++-----------
 smatch_implied.c             |  8 +++---
 smatch_links.c               |  6 ++--
 smatch_modification_hooks.c  | 12 +++-----
 smatch_param_compare_limit.c |  2 +-
 smatch_parse_call_math.c     |  2 +-
 smatch_ranges.c              |  8 +++---
 smatch_slist.c               |  4 +--
 smatch_states.c              | 18 ++++++------
 smatch_struct_assignment.c   |  2 +-
 smatch_sval.c                |  8 +++---
 21 files changed, 151 insertions(+), 93 deletions(-)

diff --git a/check_kernel_printf.c b/check_kernel_printf.c
index daf6264..ecc645e 100644
--- a/check_kernel_printf.c
+++ b/check_kernel_printf.c
@@ -345,7 +345,7 @@ static void typedef_lookup(struct typedef_lookup *tl)
 		return;
 	tl->sym = _typedef_lookup(tl->name);
 	if (!tl->sym) {
-		sm_msg("internal error: could not find typedef '%s'", tl->name);
+		sm_perror(" could not find typedef '%s'", tl->name);
 		tl->failed = 1;
 	}
 }
diff --git a/check_memcpy_overflow.c b/check_memcpy_overflow.c
index a6cc093..578c70f 100644
--- a/check_memcpy_overflow.c
+++ b/check_memcpy_overflow.c
@@ -325,7 +325,7 @@ static void register_funcs_from_file(void)
 		token = token->next;
 	}
 	if (token_type(token) != TOKEN_STREAMEND)
-		printf("internal: error parsing '%s'\n", name);
+		sm_perror("parsing '%s'", name);
 	clear_token_alloc();
 }
 
diff --git a/check_rosenberg.c b/check_rosenberg.c
index 01544cd..67cf7fe 100644
--- a/check_rosenberg.c
+++ b/check_rosenberg.c
@@ -75,7 +75,7 @@ static int check_struct(struct expression *expr, struct symbol *type)
 		}
 
 		if (!tmp->ctype.alignment) {
-			sm_msg("warn: cannot determine the alignment here\n");
+			sm_perror("cannot determine the alignment here");
 		} else if (align % tmp->ctype.alignment) {
 			print_holey_warning(expr, prev);
 			return 1;
diff --git a/check_uninitialized.c b/check_uninitialized.c
index 97d0791..7d55320 100644
--- a/check_uninitialized.c
+++ b/check_uninitialized.c
@@ -125,7 +125,7 @@ static void match_dereferences(struct expression *expr)
 		return;
 
 	name = expr_to_str(expr->unop);
-	sm_msg("error: potentially dereferencing uninitialized '%s'.", name);
+	sm_error("potentially dereferencing uninitialized '%s'.", name);
 	free_string(name);
 
 	set_state_expr(my_id, expr->unop, &initialized);
@@ -145,7 +145,7 @@ static void match_condition(struct expression *expr)
 		return;
 
 	name = expr_to_str(expr);
-	sm_msg("error: potentially using uninitialized '%s'.", name);
+	sm_error("potentially using uninitialized '%s'.", name);
 	free_string(name);
 
 	set_state_expr(my_id, expr, &initialized);
@@ -167,7 +167,7 @@ static void match_call(struct expression *expr)
 			continue;
 
 		name = expr_to_str(arg);
-		sm_msg("warn: passing uninitialized '%s'", name);
+		sm_warning("warn: passing uninitialized '%s'", name);
 		free_string(name);
 
 		set_state_expr(my_id, arg, &initialized);
@@ -228,7 +228,7 @@ static void match_call_struct_members(struct expression *expr)
 			snprintf(buf, sizeof(buf), "$->%s", sm->name + strlen(arg_name) + 1);
 			if (!member_is_used(expr, param, buf))
 				goto free;
-			sm_msg("warn: struct member %s is uninitialized", sm->name);
+			sm_warning("struct member %s is uninitialized", sm->name);
 		} END_FOR_EACH_SM(sm);
 
 free:
@@ -278,7 +278,7 @@ static void match_symbol(struct expression *expr)
 		return;
 
 	name = expr_to_str(expr);
-	sm_msg("error: uninitialized symbol '%s'.", name);
+	sm_error("uninitialized symbol '%s'.", name);
 	free_string(name);
 
 	set_state_expr(my_id, expr, &initialized);
diff --git a/check_wrong_size_arg.c b/check_wrong_size_arg.c
index 7b0baab..2a8b8d5 100644
--- a/check_wrong_size_arg.c
+++ b/check_wrong_size_arg.c
@@ -83,7 +83,7 @@ static void register_funcs_from_file(void)
 
 	}
 	if (token_type(token) != TOKEN_STREAMEND)
-		sm_msg("internal: problem parsing '%s'\n", name);
+		sm_perror("problem parsing '%s'", name);
 	clear_token_alloc();
 }
 
diff --git a/smatch.c b/smatch.c
index bc2be4d..8ec103d 100644
--- a/smatch.c
+++ b/smatch.c
@@ -41,10 +41,15 @@ int option_file_output;
 int option_time;
 int option_mem;
 char *option_datadir_str;
+int option_fatal_checks;
+
 FILE *sm_outfd;
 FILE *sql_outfd;
 FILE *caller_info_fd;
 
+int sm_nr_errors;
+int sm_nr_checks;
+
 bool __silence_warnings_for_stmt;
 
 typedef void (*reg_func) (int id);
@@ -87,7 +92,7 @@ static void show_checks(void)
 		if (!strncmp(reg_funcs[i].name, "check_", 6))
 			printf("%3d. %s\n", i, reg_funcs[i].name);
 	}
-	exit(1);
+	exit(0);
 }
 
 static void enable_disable_checks(char *s, bool enable)
@@ -117,10 +122,9 @@ static void enable_disable_checks(char *s, bool enable)
 			}
 		}
 
-		if (i == ARRAY_SIZE(reg_funcs)) {
-			printf("error: '%s' not found", s);
-			exit(1);
-		}
+		if (i == ARRAY_SIZE(reg_funcs))
+			sm_fatal("'%s' not found", s);
+
 	} while ((s = next));
 }
 
@@ -139,6 +143,7 @@ static void help(void)
 	printf("--assume-loops:  assume loops always go through at least once.\n");
 	printf("--two-passes:  use a two pass system for each function.\n");
 	printf("--file-output:  instead of printing stdout, print to \"file.c.smatch_out\".\n");
+	printf("--fatal-checks: check output is treated as an error.\n");
 	printf("--help:  print this helpful message.\n");
 	exit(1);
 }
@@ -209,6 +214,7 @@ void parse_args(int *argcp, char ***argvp)
 			option_disable = 1;
 		}
 
+		OPTION(fatal_checks);
 		OPTION(spammy);
 		OPTION(info);
 		OPTION(debug);
@@ -266,7 +272,7 @@ static char *get_data_dir(char *arg0)
 
 	if (option_datadir_str) {
 		if (access(option_datadir_str, R_OK))
-			printf("Warning: %s is not accessible -- ignore.\n",
+			sm_warning("%s is not accessible -- ignored.",
 					option_datadir_str);
 		else
 			return alloc_string(option_datadir_str);
@@ -290,8 +296,8 @@ static char *get_data_dir(char *arg0)
 	if (!access(dir, R_OK))
 		return dir;
 
-	printf("Warning: %s is not accessible.\n", dir);
-	printf("Use --no-data or --data to suppress this message.\n");
+	sm_warning("%s is not accessible.", dir);
+	sm_warning("Use --no-data or --data to suppress this message.");
 	return NULL;
 }
 
@@ -303,8 +309,12 @@ int main(int argc, char **argv)
 	sm_outfd = stdout;
 	sql_outfd = stdout;
 	caller_info_fd = stdout;
+
 	parse_args(&argc, &argv);
 
+	if (argc < 2)
+		help();
+
 	/* this gets set back to zero when we parse the first function */
 	final_pass = 1;
 
@@ -326,5 +336,10 @@ int main(int argc, char **argv)
 
 	smatch(argc, argv);
 	free_string(data_dir);
+
+	if (sm_nr_errors > 0)
+		return 1;
+	if (sm_nr_checks > 0 && option_fatal_checks)
+		return 1;
 	return 0;
 }
diff --git a/smatch.h b/smatch.h
index 6dae693..737ca48 100644
--- a/smatch.h
+++ b/smatch.h
@@ -211,6 +211,22 @@ void set_path_impossible(void);
 extern FILE *sm_outfd;
 extern FILE *sql_outfd;
 extern FILE *caller_info_fd;
+extern int sm_nr_checks;
+extern int sm_nr_errors;
+
+/*
+ * How to use these routines:
+ *
+ * sm_fatal(): an internal error of some kind that should immediately exit
+ * sm_ierror(): an internal error
+ * sm_perror(): an internal error from parsing input source
+ * sm_error(): an error from input source
+ * sm_warning(): a warning from input source
+ * sm_info(): info message (from option_info)
+ * sm_debug(): debug message
+ * sm_msg(): other message (please avoid using this)
+ */
+
 #define sm_printf(msg...) do { if (final_pass || option_debug || local_debug) fprintf(sm_outfd, msg); } while (0)
 
 static inline void sm_prefix(void)
@@ -222,7 +238,7 @@ static inline void print_implied_debug_msg();
 
 extern bool __silence_warnings_for_stmt;
 
-#define sm_msg(msg...) \
+#define sm_print_msg(type, msg...) \
 do {                                                           \
 	print_implied_debug_msg();                             \
 	if (!final_pass && !option_debug && !local_debug)      \
@@ -232,10 +248,22 @@ do {                                                           \
 	if (!option_info && is_silenced_function())	       \
 		break;					       \
 	sm_prefix();					       \
+	if (type == 1) {				       \
+		sm_printf("warn: ");			       \
+		sm_nr_checks++;			    	       \
+	} else if (type == 2) {				       \
+		sm_printf("error: ");			       \
+		sm_nr_checks++;				       \
+	} else if (type == 3) {				       \
+		sm_printf("parse error: ");		       \
+		sm_nr_errors++;				       \
+	}						       \
         sm_printf(msg);                                        \
         sm_printf("\n");                                       \
 } while (0)
 
+#define sm_msg(msg...) do { sm_print_msg(0, msg); } while (0)
+
 #define local_debug(msg...)					\
 do {								\
 	if (local_debug)					\
@@ -266,6 +294,37 @@ static inline void print_implied_debug_msg(void)
 	}							\
 } while(0)
 
+#define sm_warning(msg...) do { sm_print_msg(1, msg); } while (0)
+#define sm_error(msg...) do { sm_print_msg(2, msg); } while (0)
+#define sm_perror(msg...) do { sm_print_msg(3, msg); } while (0)
+
+static inline void sm_fatal(const char *fmt, ...)
+{
+	va_list args;
+
+	va_start(args, fmt);
+	vfprintf(sm_outfd, fmt, args);
+	va_end(args);
+
+	fprintf(sm_outfd, "\n");
+
+	exit(1);
+}
+
+static inline void sm_ierror(const char *fmt, ...)
+{
+	va_list args;
+
+	sm_nr_errors++;
+
+	fprintf(sm_outfd, "internal error: ");
+
+	va_start(args, fmt);
+	vfprintf(sm_outfd, fmt, args);
+	va_end(args);
+
+	fprintf(sm_outfd, "\n");
+}
 #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
 
 struct smatch_state *__get_state(int owner, const char *name, struct symbol *sym);
@@ -842,8 +901,8 @@ do {										\
 		sm_debug("mem-db: %s\n", buf);					\
 		rc = sqlite3_exec(_db, buf, NULL, NULL, &err);			\
 		if (rc != SQLITE_OK) {						\
-			fprintf(stderr, "SQL error #2: %s\n", err);		\
-			fprintf(stderr, "SQL: '%s'\n", buf);			\
+			sm_ierror("SQL error #2: %s", err);			\
+			sm_ierror("SQL: '%s'", buf);				\
 			parse_error = 1;					\
 		}								\
 		break;								\
diff --git a/smatch_auto_copy.c b/smatch_auto_copy.c
index 127589f..098404e 100644
--- a/smatch_auto_copy.c
+++ b/smatch_auto_copy.c
@@ -25,7 +25,7 @@ static int *auto_copy;
 void set_auto_copy(int owner)
 {
 	if (owner <= 1 || owner > num_checks) {
-		printf("bogus set_auto_copy()\n");
+		sm_ierror("bogus set_auto_copy()");
 		return;
 	}
 	auto_copy[owner] = 1;
diff --git a/smatch_comparison.c b/smatch_comparison.c
index b0aa0ba..51b4a45 100644
--- a/smatch_comparison.c
+++ b/smatch_comparison.c
@@ -117,7 +117,7 @@ int flip_comparison(int op)
 	case SPECIAL_UNSIGNED_GT:
 		return SPECIAL_UNSIGNED_LT;
 	default:
-		sm_msg("internal smatch bug.  unhandled comparison %d", op);
+		sm_perror("unhandled comparison %d", op);
 		return op;
 	}
 }
@@ -148,7 +148,7 @@ int negate_comparison(int op)
 	case SPECIAL_UNSIGNED_GT:
 		return SPECIAL_UNSIGNED_LTE;
 	default:
-		sm_msg("internal smatch bug.  unhandled comparison %d", op);
+		sm_perror("unhandled comparison %d", op);
 		return op;
 	}
 }
@@ -2311,7 +2311,7 @@ static int parse_comparison(char **value, int *op)
 	}
 
 	if (**value != ' ') {
-		sm_msg("internal error parsing comparison.  %s", *value);
+		sm_perror("parsing comparison.  %s", *value);
 		return 0;
 	}
 
diff --git a/smatch_db.c b/smatch_db.c
index bb1a705..b431f01 100644
--- a/smatch_db.c
+++ b/smatch_db.c
@@ -107,8 +107,8 @@ void sql_exec(struct sqlite3 *db, int (*callback)(void*, int, char**, char**), v
 
 	rc = sqlite3_exec(db, sql, callback, data, &err);
 	if (rc != SQLITE_OK && !parse_error) {
-		fprintf(stderr, "SQL error #2: %s\n", err);
-		fprintf(stderr, "SQL: '%s'\n", sql);
+		sm_ierror("SQL error #2: %s", err);
+		sm_ierror("SQL: '%s'", sql);
 		parse_error = 1;
 	}
 }
@@ -2116,7 +2116,7 @@ static void init_memdb(void)
 
 	rc = sqlite3_open(":memory:", &mem_db);
 	if (rc != SQLITE_OK) {
-		printf("Error starting In-Memory database.");
+		sm_ierror("starting In-Memory database.");
 		return;
 	}
 
@@ -2126,20 +2126,20 @@ static void init_memdb(void)
 			continue;
 		ret = read(fd, buf, sizeof(buf));
 		if (ret < 0) {
-			printf("failed to read: %s\n", schema_files[i]);
+			sm_ierror("failed to read: %s", schema_files[i]);
 			continue;
 		}
 		close(fd);
 		if (ret == sizeof(buf)) {
-			printf("Schema file too large:  %s (limit %zd bytes)",
+			sm_ierror("Schema file too large:  %s (limit %zd bytes)",
 			       schema_files[i], sizeof(buf));
 			continue;
 		}
 		buf[ret] = '\0';
 		rc = sqlite3_exec(mem_db, buf, NULL, NULL, &err);
 		if (rc != SQLITE_OK) {
-			fprintf(stderr, "SQL error #2: %s\n", err);
-			fprintf(stderr, "%s\n", buf);
+			sm_ierror("SQL error #2: %s", err);
+			sm_ierror("%s", buf);
 		}
 	}
 }
@@ -2162,7 +2162,7 @@ static void init_cachedb(void)
 
 	rc = sqlite3_open(":memory:", &cache_db);
 	if (rc != SQLITE_OK) {
-		printf("Error starting In-Memory database.");
+		sm_ierror("starting In-Memory database.");
 		return;
 	}
 
@@ -2172,20 +2172,20 @@ static void init_cachedb(void)
 			continue;
 		ret = read(fd, buf, sizeof(buf));
 		if (ret < 0) {
-			printf("failed to read: %s\n", schema_files[i]);
+			sm_ierror("failed to read: %s", schema_files[i]);
 			continue;
 		}
 		close(fd);
 		if (ret == sizeof(buf)) {
-			printf("Schema file too large:  %s (limit %zd bytes)",
+			sm_ierror("Schema file too large:  %s (limit %zd bytes)",
 			       schema_files[i], sizeof(buf));
 			continue;
 		}
 		buf[ret] = '\0';
 		rc = sqlite3_exec(cache_db, buf, NULL, NULL, &err);
 		if (rc != SQLITE_OK) {
-			fprintf(stderr, "SQL error #2: %s\n", err);
-			fprintf(stderr, "%s\n", buf);
+			sm_ierror("SQL error #2: %s", err);
+			sm_ierror("%s", buf);
 		}
 	}
 }
@@ -2294,7 +2294,7 @@ static char *get_next_string(char **str)
 	if (len > 256) {
 		memcpy(string, start, 255);
 		string[255] = '\0';
-		printf("return_fix: '%s' too long", string);
+		sm_ierror("return_fix: '%s' too long", string);
 		**str = '\0';
 		return NULL;
 	}
@@ -2323,7 +2323,7 @@ static void register_return_replacements(void)
 	if (ret < 0)
 		return;
 	if (ret == sizeof(buf)) {
-		printf("file too large:  %s (limit %zd bytes)",
+		sm_ierror("file too large:  %s (limit %zd bytes)",
 		       filename, sizeof(buf));
 		return;
 	}
diff --git a/smatch_flow.c b/smatch_flow.c
index 986160d..31503d5 100644
--- a/smatch_flow.c
+++ b/smatch_flow.c
@@ -1072,7 +1072,7 @@ void __split_stmt(struct statement *stmt)
 
 		__bail_on_rest_of_function = 1;
 		final_pass = 1;
-		sm_msg("Function too hairy.  Giving up. %lu seconds",
+		sm_perror("Function too hairy.  Giving up. %lu seconds",
 		       stop.tv_sec - fn_start_time.tv_sec);
 		fake_a_return();
 		final_pass = 0;  /* turn off sm_msg() from here */
@@ -1891,27 +1891,21 @@ static void open_output_files(char *base_file)
 
 	snprintf(buf, sizeof(buf), "%s.smatch", base_file);
 	sm_outfd = fopen(buf, "w");
-	if (!sm_outfd) {
-		printf("Error:  Cannot open %s\n", buf);
-		exit(1);
-	}
+	if (!sm_outfd)
+		sm_fatal("Cannot open %s", buf);
 
 	if (!option_info)
 		return;
 
 	snprintf(buf, sizeof(buf), "%s.smatch.sql", base_file);
 	sql_outfd = fopen(buf, "w");
-	if (!sql_outfd) {
-		printf("Error:  Cannot open %s\n", buf);
-		exit(1);
-	}
+	if (!sql_outfd)
+		sm_fatal("Error:  Cannot open %s", buf);
 
 	snprintf(buf, sizeof(buf), "%s.smatch.caller_info", base_file);
 	caller_info_fd = fopen(buf, "w");
-	if (!caller_info_fd) {
-		printf("Error:  Cannot open %s\n", buf);
-		exit(1);
-	}
+	if (!caller_info_fd)
+		sm_fatal("Error:  Cannot open %s", buf);
 }
 
 void smatch(int argc, char **argv)
@@ -1924,10 +1918,6 @@ void smatch(int argc, char **argv)
 
 	gettimeofday(&start, NULL);
 
-	if (argc < 2) {
-		printf("Usage:  smatch [--debug] <filename.c>\n");
-		exit(1);
-	}
 	sparse_initialize(argc, argv, &filelist);
 	set_valid_ptr_max();
 	alloc_valid_ptr_rl();
diff --git a/smatch_implied.c b/smatch_implied.c
index fc86de2..0a137de 100644
--- a/smatch_implied.c
+++ b/smatch_implied.c
@@ -134,7 +134,7 @@ static int create_fake_history(struct sm_state *sm, int comparison, struct range
 		return 0;
 
 	if (rl_intersection(true_rl, false_rl)) {
-		sm_msg("internal error parsing (%s (%s) %s %s)",
+		sm_perror("parsing (%s (%s) %s %s)",
 			sm->name, sm->state->name, show_special(comparison), show_rl(rl));
 		sm_msg("true_rl = %s false_rl = %s intersection = %s",
 		       show_rl(true_rl), show_rl(false_rl), show_rl(rl_intersection(true_rl, false_rl)));
@@ -142,7 +142,7 @@ static int create_fake_history(struct sm_state *sm, int comparison, struct range
 	}
 
 	if (option_debug)
-		sm_msg("fake_history: %s vs %s.  %s %s %s. --> T: %s F: %s",
+		sm_info("fake_history: %s vs %s.  %s %s %s. --> T: %s F: %s",
 		       sm->name, show_rl(rl), sm->state->name, show_special(comparison), show_rl(rl),
 		       show_rl(true_rl), show_rl(false_rl));
 
@@ -403,7 +403,7 @@ static int taking_too_long(void)
 		return 0;
 
 	if (!__inline_fn && printed != cur_func_sym) {
-		sm_msg("internal: turning off implications after 60 seconds");
+		sm_perror("turning off implications after 60 seconds");
 		printed = cur_func_sym;
 	}
 	return 1;
@@ -596,7 +596,7 @@ static void separate_and_filter(struct sm_state *sm, int comparison, struct rang
 	sec = time_after.tv_sec - time_before.tv_sec;
 	if (sec > 20) {
 		sm->nr_children = 4000;
-		sm_msg("Function too hairy.  Ignoring implications after %d seconds.", sec);
+		sm_perror("Function too hairy.  Ignoring implications after %d seconds.", sec);
 	}
 }
 
diff --git a/smatch_links.c b/smatch_links.c
index 91907b5..c24f0c2 100644
--- a/smatch_links.c
+++ b/smatch_links.c
@@ -99,10 +99,8 @@ static void match_link_modify(struct sm_state *sm, struct expression *mod_expr)
 
 void set_up_link_functions(int id, int link_id)
 {
-	if (id + 1 != link_id) {
-		printf("FATAL ERROR: links need to be registered directly after the check");
-		exit(1);
-	}
+	if (id + 1 != link_id)
+		sm_fatal("FATAL ERROR: links need to be registered directly after the check");
 
 	add_merge_hook(link_id, &merge_link_states);
 	add_modification_hook(link_id, &match_link_modify);
diff --git a/smatch_modification_hooks.c b/smatch_modification_hooks.c
index 7eef7a7..b4f9e62 100644
--- a/smatch_modification_hooks.c
+++ b/smatch_modification_hooks.c
@@ -68,19 +68,15 @@ static struct smatch_state *alloc_my_state(struct expression *expr, struct smatc
 
 void add_modification_hook(int owner, modification_hook *call_back)
 {
-	if (hooks[owner]) {
-		printf("multiple modification hooks for %s\n", check_name(owner));
-		exit(1);
-	}
+	if (hooks[owner])
+		sm_fatal("multiple modification hooks for %s", check_name(owner));
 	hooks[owner] = call_back;
 }
 
 void add_modification_hook_late(int owner, modification_hook *call_back)
 {
-	if (hooks_late[owner]) {
-		printf("multiple late modification hooks for %s\n", check_name(owner));
-		exit(1);
-	}
+	if (hooks_late[owner])
+		sm_fatal("multiple late modification hooks for %s", check_name(owner));
 	hooks_late[owner] = call_back;
 }
 
diff --git a/smatch_param_compare_limit.c b/smatch_param_compare_limit.c
index acdfed9..1539e06 100644
--- a/smatch_param_compare_limit.c
+++ b/smatch_param_compare_limit.c
@@ -268,7 +268,7 @@ static int parse_comparison(char **value, int *op)
 	}
 
 	if (**value != ' ') {
-		sm_msg("internal error parsing comparison.  %s", *value);
+		sm_perror("parsing comparison.  %s", *value);
 		return 0;
 	}
 
diff --git a/smatch_parse_call_math.c b/smatch_parse_call_math.c
index 19b9e95..a84622d 100644
--- a/smatch_parse_call_math.c
+++ b/smatch_parse_call_math.c
@@ -51,7 +51,7 @@ static char pop_op(void)
 	char c;
 
 	if (!op_list) {
-		sm_msg("internal smatch error %s", __func__);
+		sm_perror("%s: no op_list", __func__);
 		return '\0';
 	}
 
diff --git a/smatch_ranges.c b/smatch_ranges.c
index afae441..fbc93fe 100644
--- a/smatch_ranges.c
+++ b/smatch_ranges.c
@@ -311,7 +311,7 @@ void filter_by_comparison(struct range_list **rl, int comparison, struct range_l
 			ret_rl = remove_range(left_orig, rl_min(right_orig), rl_min(right_orig));
 		break;
 	default:
-		sm_msg("internal error: unhandled comparison %s", show_special(comparison));
+		sm_perror("unhandled comparison %s", show_special(comparison));
 		return;
 	}
 
@@ -949,7 +949,7 @@ int true_comparison_range(struct data_range *left, int comparison, struct data_r
 			return 1;
 		return 0;
 	default:
-		sm_msg("unhandled comparison %d\n", comparison);
+		sm_perror("unhandled comparison %d", comparison);
 		return 0;
 	}
 	return 0;
@@ -1001,7 +1001,7 @@ static int false_comparison_range_sval(struct data_range *left, int comparison,
 			return 0;
 		return 1;
 	default:
-		sm_msg("unhandled comparison %d\n", comparison);
+		sm_perror("unhandled comparison %d", comparison);
 		return 0;
 	}
 	return 0;
@@ -1829,7 +1829,7 @@ void split_comparison_rl(struct range_list *left_orig, int op, struct range_list
 			right_true = remove_range(right_orig, rl_min(left_orig), rl_min(left_orig));
 		break;
 	default:
-		sm_msg("internal error: unhandled comparison %d", op);
+		sm_perror(" unhandled comparison %d", op);
 		return;
 	}
 
diff --git a/smatch_slist.c b/smatch_slist.c
index 4c74caf..0a993e9 100644
--- a/smatch_slist.c
+++ b/smatch_slist.c
@@ -757,7 +757,7 @@ static void __merge_stree(struct stree **to, struct stree *stree, int add_pool)
 		if (!one_iter.sm || !two_iter.sm)
 			break;
 		if (cmp_tracker(one_iter.sm, two_iter.sm) < 0) {
-			sm_msg("error:  Internal smatch error.");
+			sm_perror(" in %s", __func__);
 			avl_iter_next(&one_iter);
 		} else if (cmp_tracker(one_iter.sm, two_iter.sm) == 0) {
 			if (add_pool && one_iter.sm != two_iter.sm) {
@@ -775,7 +775,7 @@ static void __merge_stree(struct stree **to, struct stree *stree, int add_pool)
 			avl_iter_next(&one_iter);
 			avl_iter_next(&two_iter);
 		} else {
-			sm_msg("error:  Internal smatch error.");
+			sm_perror(" in %s", __func__);
 			avl_iter_next(&two_iter);
 		}
 	}
diff --git a/smatch_states.c b/smatch_states.c
index 53ed75c..c7a9c85 100644
--- a/smatch_states.c
+++ b/smatch_states.c
@@ -88,7 +88,7 @@ struct sm_state *set_state(int owner, const char *name, struct symbol *sym, stru
 		return NULL;
 
 	if (read_only)
-		sm_msg("Smatch Internal Error: cur_stree is read only.");
+		sm_perror("cur_stree is read only.");
 
 	if (option_debug || strcmp(check_name(owner), option_debug_check) == 0) {
 		struct smatch_state *s;
@@ -145,7 +145,7 @@ void __push_fake_cur_stree(void)
 struct stree *__pop_fake_cur_stree(void)
 {
 	if (!fake_cur_stree_stack)
-		sm_msg("INTERNAL error: popping too many fake cur strees.");
+		sm_perror("popping too many fake cur strees.");
 	__use_pre_cond_states();
 	return pop_stree(&fake_cur_stree_stack);
 }
@@ -190,7 +190,7 @@ void __merge_stree_into_cur(struct stree *stree)
 void __set_sm(struct sm_state *sm)
 {
 	if (read_only)
-		sm_msg("Smatch Internal Error: cur_stree is read only.");
+		sm_perror("cur_stree is read only.");
 
 	if (option_debug ||
 	    strcmp(check_name(sm->owner), option_debug_check) == 0) {
@@ -216,7 +216,7 @@ void __set_sm(struct sm_state *sm)
 void __set_sm_cur_stree(struct sm_state *sm)
 {
 	if (read_only)
-		sm_msg("Smatch Internal Error: cur_stree is read only.");
+		sm_perror("cur_stree is read only.");
 
 	if (option_debug ||
 	    strcmp(check_name(sm->owner), option_debug_check) == 0) {
@@ -239,7 +239,7 @@ void __set_sm_cur_stree(struct sm_state *sm)
 void __set_sm_fake_stree(struct sm_state *sm)
 {
 	if (read_only)
-		sm_msg("Smatch Internal Error: cur_stree is read only.");
+		sm_perror("cur_stree is read only.");
 
 	if (option_debug ||
 	    strcmp(check_name(sm->owner), option_debug_check) == 0) {
@@ -472,7 +472,7 @@ void set_true_false_states(int owner, const char *name, struct symbol *sym,
 			   struct smatch_state *false_state)
 {
 	if (read_only)
-		sm_msg("Smatch Internal Error: cur_stree is read only.");
+		sm_perror("cur_stree is read only.");
 
 	if (option_debug || strcmp(check_name(owner), option_debug_check) == 0) {
 		struct smatch_state *tmp;
@@ -487,7 +487,7 @@ void set_true_false_states(int owner, const char *name, struct symbol *sym,
 		return;
 
 	if (!cond_false_stack || !cond_true_stack) {
-		printf("Error:  missing true/false stacks\n");
+		sm_perror("missing true/false stacks");
 		return;
 	}
 
@@ -539,7 +539,7 @@ void __set_true_false_sm(struct sm_state *true_sm, struct sm_state *false_sm)
 	}
 
 	if (!cond_false_stack || !cond_true_stack) {
-		printf("Error:  missing true/false stacks\n");
+		sm_perror("missing true/false stacks");
 		return;
 	}
 
@@ -586,7 +586,7 @@ int __path_is_null(void)
 static void check_stree_stack_free(struct stree_stack **stack)
 {
 	if (*stack) {
-		sm_msg("smatch internal error:  stack not empty");
+		sm_perror("stack not empty");
 		free_stack_and_strees(stack);
 	}
 }
diff --git a/smatch_struct_assignment.c b/smatch_struct_assignment.c
index 90b666f..1929c95 100644
--- a/smatch_struct_assignment.c
+++ b/smatch_struct_assignment.c
@@ -285,7 +285,7 @@ static void __struct_members_copy(int mode, struct expression *faked,
 			break;
 		}
 		if (!right_member) {
-			sm_msg("internal.  No right member");
+			sm_perror("No right member");
 			continue;
 		}
 		assign = assign_expression(left_member, '=', right_member);
diff --git a/smatch_sval.c b/smatch_sval.c
index 9d892a0..725509a 100644
--- a/smatch_sval.c
+++ b/smatch_sval.c
@@ -339,7 +339,7 @@ static sval_t sval_binop_unsigned(struct symbol *type, sval_t left, int op, sval
 		break;
 	case '%':
 		if (right.uvalue == 0) {
-			sm_msg("internal error: %s: MOD by zero", __func__);
+			sm_perror(" %s: MOD by zero", __func__);
 			ret.uvalue = 123456789;
 		} else {
 			ret.uvalue = left.uvalue % right.uvalue;
@@ -361,7 +361,7 @@ static sval_t sval_binop_unsigned(struct symbol *type, sval_t left, int op, sval
 		ret.uvalue = left.uvalue ^ right.uvalue;
 		break;
 	default:
-		sm_msg("internal error: %s: unhandled binop %s", __func__,
+		sm_perror(" %s: unhandled binop %s", __func__,
 		       show_special(op));
 		ret.uvalue = 1234567;
 	}
@@ -397,7 +397,7 @@ static sval_t sval_binop_signed(struct symbol *type, sval_t left, int op, sval_t
 		break;
 	case '%':
 		if (right.value == 0) {
-			sm_msg("internal error: %s: MOD by zero", __func__);
+			sm_perror(" %s: MOD by zero", __func__);
 			ret.value = 123456789;
 		} else {
 			ret.value = left.value % right.value;
@@ -419,7 +419,7 @@ static sval_t sval_binop_signed(struct symbol *type, sval_t left, int op, sval_t
 		ret.value = left.value ^ right.value;
 		break;
 	default:
-		sm_msg("internal error: %s: unhandled binop %s", __func__,
+		sm_perror(" %s: unhandled binop %s", __func__,
 		       show_special(op));
 		ret.value = 1234567;
 	}
-- 
1.8.3.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.