--- old/usr/src/tools/smatch/src/smatch_helper.c	Tue May 19 02:50:33 2020
+++ new/usr/src/tools/smatch/src/smatch_helper.c	Tue May 19 02:50:33 2020
@@ -147,7 +147,7 @@
 	return NULL;
 }
 
-static struct expression *get_array_expr(struct expression *expr)
+struct expression *get_array_expr(struct expression *expr)
 {
 	struct expression *parent;
 	struct symbol *type;
@@ -174,10 +174,8 @@
 
 static void __get_variable_from_expr(struct symbol **sym_ptr, char *buf,
 				     struct expression *expr, int len,
-				     int *complicated, int no_parens)
+				     int *complicated)
 {
-
-
 	if (!expr) {
 		/* can't happen on valid code */
 		*complicated = 1;
@@ -204,7 +202,7 @@
 			}
 		}
 
-		__get_variable_from_expr(sym_ptr, buf, deref, len, complicated, no_parens);
+		__get_variable_from_expr(sym_ptr, buf, deref, len, complicated);
 
 		if (op == '*')
 			append(buf, "->", len);
@@ -236,7 +234,7 @@
 		}
 
 		if (expr->op == '(') {
-			if (!no_parens && expr->unop->type != EXPR_SYMBOL)
+			if (expr->unop->type != EXPR_SYMBOL)
 				append(buf, "(", len);
 		} else if (expr->op != '*' || !get_array_expr(expr->unop)) {
 			tmp = show_special(expr->op);
@@ -243,13 +241,13 @@
 			append(buf, tmp, len);
 		}
 		__get_variable_from_expr(sym_ptr, buf, expr->unop,
-						 len, complicated, no_parens);
+						 len, complicated);
 
-		if (expr->op == '(' && !no_parens && expr->unop->type != EXPR_SYMBOL)
+		if (expr->op == '(' && expr->unop->type != EXPR_SYMBOL)
 			append(buf, ")", len);
 
 		if (expr->op == SPECIAL_DECREMENT ||
-				expr->op == SPECIAL_INCREMENT)
+		    expr->op == SPECIAL_INCREMENT)
 			*complicated = 1;
 
 		return;
@@ -258,7 +256,7 @@
 		const char *tmp;
 
 		__get_variable_from_expr(sym_ptr, buf, expr->unop,
-						 len, complicated, no_parens);
+						 len, complicated);
 		tmp = show_special(expr->op);
 		append(buf, tmp, len);
 
@@ -276,14 +274,14 @@
 		*complicated = 1;
 		array_expr = get_array_expr(expr);
 		if (array_expr) {
-			__get_variable_from_expr(sym_ptr, buf, array_expr, len, complicated, no_parens);
+			__get_variable_from_expr(sym_ptr, buf, array_expr, len, complicated);
 			append(buf, "[", len);
 		} else {
-			__get_variable_from_expr(sym_ptr, buf, expr->left, len, complicated, no_parens);
+			__get_variable_from_expr(sym_ptr, buf, expr->left, len, complicated);
 			snprintf(tmp, sizeof(tmp), " %s ", show_special(expr->op));
 			append(buf, tmp, len);
 		}
-		__get_variable_from_expr(NULL, buf, expr->right, len, complicated, no_parens);
+		__get_variable_from_expr(NULL, buf, expr->right, len, complicated);
 		if (array_expr)
 			append(buf, "]", len);
 		return;
@@ -321,13 +319,13 @@
 		int i;
 
 		*complicated = 1;
-		__get_variable_from_expr(NULL, buf, expr->fn, len, complicated, no_parens);
+		__get_variable_from_expr(NULL, buf, expr->fn, len, complicated);
 		append(buf, "(", len);
 		i = 0;
 		FOR_EACH_PTR(expr->args, tmp) {
 			if (i++)
 				append(buf, ", ", len);
-			__get_variable_from_expr(NULL, buf, tmp, len, complicated, no_parens);
+			__get_variable_from_expr(NULL, buf, tmp, len, complicated);
 		} END_FOR_EACH_PTR(tmp);
 		append(buf, ")", len);
 		return;
@@ -336,7 +334,7 @@
 	case EXPR_FORCE_CAST:
 		__get_variable_from_expr(sym_ptr, buf,
 					 expr->cast_expression, len,
-					 complicated, no_parens);
+					 complicated);
 		return;
 	case EXPR_SIZEOF: {
 		sval_t sval;
@@ -358,16 +356,30 @@
 		if (expr->expr_ident)
 			append(buf, expr->expr_ident->name, len);
 		return;
-	default:
+	case EXPR_SELECT:
+	case EXPR_CONDITIONAL:
 		*complicated = 1;
-		//printf("unknown type = %d\n", expr->type);
+		append(buf, "(", len);
+		__get_variable_from_expr(NULL, buf, expr->conditional, len, complicated);
+		append(buf, ") ?", len);
+		if (expr->cond_true)
+			__get_variable_from_expr(NULL, buf, expr->cond_true, len, complicated);
+		append(buf, ":", len);
+		__get_variable_from_expr(NULL, buf, expr->cond_false, len, complicated);
 		return;
+	default: {
+			char tmp[64];
+
+			snprintf(tmp, sizeof(tmp), "$expr_%p(%d)", expr, expr->type);
+			append(buf, tmp, len);
+			*complicated = 1;
+		}
+		return;
 	}
 }
 
 struct expr_str_cache_results {
 	struct expression *expr;
-	int no_parens;
 	char str[VAR_LEN];
 	struct symbol *sym;
 	int complicated;
@@ -375,7 +387,7 @@
 
 static void get_variable_from_expr(struct symbol **sym_ptr, char *buf,
 				     struct expression *expr, int len,
-				     int *complicated, int no_parens)
+				     int *complicated)
 {
 	static struct expr_str_cache_results cached[8];
 	struct symbol *tmp_sym = NULL;
@@ -383,8 +395,7 @@
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(cached); i++) {
-		if (expr == cached[i].expr &&
-		    no_parens == cached[i].no_parens) {
+		if (expr == cached[i].expr) {
 			strncpy(buf, cached[i].str, len);
 			if (sym_ptr)
 				*sym_ptr = cached[i].sym;
@@ -393,12 +404,14 @@
 		}
 	}
 
-	__get_variable_from_expr(&tmp_sym, buf, expr, len, complicated, no_parens);
+	__get_variable_from_expr(&tmp_sym, buf, expr, len, complicated);
 	if (sym_ptr)
 		*sym_ptr = tmp_sym;
 
+	if (expr->smatch_flags & Tmp)
+		return;
+
 	cached[idx].expr = expr;
-	cached[idx].no_parens = no_parens;
 	strncpy(cached[idx].str, buf, VAR_LEN);
 	cached[idx].sym = tmp_sym;
 	cached[idx].complicated = *complicated;
@@ -427,7 +440,7 @@
 	if (!expr)
 		return NULL;
 	get_variable_from_expr(sym_ptr, var_name, expr, sizeof(var_name),
-				 &complicated, 0);
+			       &complicated);
 	if (complicated < 2)
 		return alloc_string(var_name);
 	else
@@ -458,7 +471,7 @@
 		return NULL;
 	expr = strip_expr(expr);
 	get_variable_from_expr(sym_ptr, var_name, expr, sizeof(var_name),
-				 &complicated, 1);
+			       &complicated);
 
 	if (complicated) {
 		if (sym_ptr)
@@ -1051,9 +1064,24 @@
 	struct symbol *tmp;
 	int i;
 
-	if (!cur_func_sym)
-		return -1;
+	if (!sym)
+		return UNKNOWN_SCOPE;
 
+	if (sym->ctype.modifiers & MOD_TOPLEVEL) {
+		if (sym->ctype.modifiers & MOD_STATIC)
+			return FILE_SCOPE;
+		return GLOBAL_SCOPE;
+	}
+
+	if (!cur_func_sym) {
+		if (!parse_error) {
+			sm_msg("warn: internal.  problem with scope:  %s",
+			       sym->ident ? sym->ident->name : "<anon var>");
+		}
+		return GLOBAL_SCOPE;
+	}
+
+
 	i = 0;
 	FOR_EACH_PTR(cur_func_sym->ctype.base_type->arguments, tmp) {
 		if (tmp == sym)
@@ -1060,7 +1088,7 @@
 			return i;
 		i++;
 	} END_FOR_EACH_PTR(tmp);
-	return -1;
+	return LOCAL_SCOPE;
 }
 
 int get_param_num(struct expression *expr)
@@ -1069,11 +1097,11 @@
 	char *name;
 
 	if (!cur_func_sym)
-		return -1;
+		return UNKNOWN_SCOPE;
 	name = expr_to_var_sym(expr, &sym);
 	free_string(name);
 	if (!sym)
-		return -1;
+		return UNKNOWN_SCOPE;
 	return get_param_num_from_sym(sym);
 }
 
