<commit_before>#include <stdlib.h>
#include <string.h>

#include "ops.h"
#include "stmt_switch.h"
#include "../sue.h"
#include "../../util/alloc.h"
#include "../out/lbl.h"

const char *str_stmt_switch()
{
	return "switch";
}

void fold_switch_enum(stmt *sw, type *enum_type)
{
	const int nents = enum_nentries(enum_type->sue);
	stmt **titer;
	char *marks = umalloc(nents * sizeof *marks);
	int midx;

	/* for each case/default/case_range... */
	for(titer = sw->codes; titer && *titer; titer++){
		stmt *cse = *titer;
		int v, w;
		intval iv;

		if(cse->expr->expr_is_default)
			goto ret;

		const_fold_need_val(cse->expr, &iv);
		v = iv.val;

		if(stmt_kind(cse, case_range)){
			const_fold_need_val(cse->expr2, &iv);
			w = iv.val;
		}else{
			w = v;
		}

		for(; v <= w; v++){
			sue_member **mi;
			for(midx = 0, mi = enum_type->sue->members; *mi; midx++, mi++){
				enum_member *m = (*mi)->enum_member;

				const_fold_need_val(m->val, &iv);

				if(v == iv.val)
					marks[midx]++;
			}
		}
	}

	for(midx = 0; midx < nents; midx++)
		if(!marks[midx])
			cc1_warn_at(&sw->where, 0, 1, WARN_SWITCH_ENUM, "enum %s::%s not handled in switch",
					enum_type->sue->anon ? "" : enum_type->sue->spel,
					enum_type->sue->members[midx]->enum_member->spel);

ret:
	free(marks);
}

void fold_stmt_switch(stmt *s)
{
	symtable *test_symtab = fold_stmt_test_init_expr(s, "switch");

	s->lbl_break = out_label_flow("switch");

	FOLD_EXPR(s->expr, test_symtab);

	fold_need_expr(s->expr, "switch", 0);
<commit_msg>Check for OOB on switch(enum xyz...)<commit_after>#include <stdlib.h>
#include <string.h>

#include "ops.h"
#include "stmt_switch.h"
#include "../sue.h"
#include "../../util/alloc.h"
#include "../out/lbl.h"

const char *str_stmt_switch()
{
	return "switch";
}

void fold_switch_enum(stmt *sw, type *enum_type)
{
	const int nents = enum_nentries(enum_type->sue);
	stmt **titer;
	char *marks = umalloc(nents * sizeof *marks);
	int midx;

	/* for each case/default/case_range... */
	for(titer = sw->codes; titer && *titer; titer++){
		stmt *cse = *titer;
		int v, w;
		intval iv;

		if(cse->expr->expr_is_default)
			goto ret;

		const_fold_need_val(cse->expr, &iv);
		v = iv.val;

		if(stmt_kind(cse, case_range)){
			const_fold_need_val(cse->expr2, &iv);
			w = iv.val;
		}else{
			w = v;
		}

		for(; v <= w; v++){
			sue_member **mi;
			int found = 0;

			for(midx = 0, mi = enum_type->sue->members; *mi; midx++, mi++){
				enum_member *m = (*mi)->enum_member;

				const_fold_need_val(m->val, &iv);

				if(v == iv.val)
					marks[midx]++, found = 1;
			}

			if(!found)
				WARN_AT(&cse->where, "'case %ld' not not a member of enum %s",
						(long)v, enum_type->sue->spel);
		}
	}

	for(midx = 0; midx < nents; midx++)
		if(!marks[midx])
			cc1_warn_at(&sw->where, 0, 1, WARN_SWITCH_ENUM, "enum %s::%s not handled in switch",
					enum_type->sue->anon ? "" : enum_type->sue->spel,
					enum_type->sue->members[midx]->enum_member->spel);

ret:
	free(marks);
}

void fold_stmt_switch(stmt *s)
{
	symtable *test_symtab = fold_stmt_test_init_expr(s, "switch");

	s->lbl_break = out_label_flow("switch");

	FOLD_EXPR(s->expr, test_symtab);

	fold_need_expr(s->expr, "switch", 0);

{'fraction_non_alphanumeric': 0.19497645211930925, 'fraction_numerical': 0.005023547880690738, 'mean_word_length': 3.6852941176470586, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 54, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1847463', 'n_tokens_mistral': 1504, 'n_tokens_neox': 1355, 'n_words': 273}