Skip to content

clang feature request: warn on incorrect tagged union value access #74205

@matheusmoreira

Description

@matheusmoreira

Currently clang does not produce a warning if the value of a tagged union that doesn't correspond to its type tag is accessed.

For example, this code:

// warn.c
#include <stdio.h>

enum T { I, F };
union U { int i; float f; };
struct S { enum T t; union U u; };

int main(void) {
	struct S s = { .t = F, .u.f = 12345.67890f };
	switch (s.t) {
	case I:
		printf("%d\n", s.u.i);
		break;
	case F:
		// copied the above case
		// but neglected to update the code
		printf("%d\n", s.u.i);
		break;
	}
}

Does not produce any warning when compiled, leading to incorrect results:

$ clang -Weverything -o warn warn.c && ./warn
1178658487

I understand that unions are typically used for type punning and that such accesses are often intended by the programmer but compiler checks would still be beneficial when that's not the case. People have created C preprocessor solutions to use tagged unions safely in C. I've also seen support for safe tagged unions in newer languages like Zig.

A compiler mechanism to establish a relationship between the union values and their corresponding enum tags would be extremely useful. Something like this, perhaps:

struct S {
	enum T t;
	union U {
		int i       __attribute__((tag(t, I)));
		float f     __attribute__((tag(t, F)));
	} u;
};

Then clang would be able to warn when union values are accessed in a context where their specified tags are not known to be the correct value:

	switch (s.t) {
	case I:
		// i is accessed
		// the tag of i is t
		// t is supposed to equal I
		// compiler knows t equals I because of switch case
		// correct, no warning is emitted
		printf("%d\n", s.u.i);
		break;
	case F:
		// i is accessed
		// the tag of i is t
		// t is supposed to equal I
		// compiler knows t equals F because of switch case
		// incorrect, a warning is emitted
		printf("%d\n", s.u.i);
		break;
	}

Relevant links:

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:frontendLanguage frontend issues, e.g. anything involving "Sema"enhancementImproving things as opposed to bug fixing, e.g. new or missing feature

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions