Loading... (original) (raw)

In utilities/exceptions.hpp, the CHECK_ macro expands into multiple statements, vis.

#define CHECK_(result) THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; return result; } (void)(0

Because of this, it and its derivative CHECK_* macros, can only correctly be used within a block statement, i.e., within squigly brackets { }, and, because the 'THREAD);' terminates a statement, effectively only on the right-hand-side of an assignment expression. Using these macros in expression contexts, e.g., in a return statement, results in the pending exception check being skipped, which can mask bugs, and is also surprising behavior to the programmer.

All uses of the CHECK_ macros in expression context should be fixed. E.g., in management.cpp, there are two instances of

return initialize_klass(k, CHECK_NULL);

which expand to

return initialize_klass(k, THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; return NULL; } (void)(0);

The pending exception check is skipped. The code should be something like

InstanceKlass* ik = initialize_klass(k, CHECK_NULL);
return ik;

JDK-8062808

patched some uses of CHECK_NULL in return statements by replacing CHECK_NULL with THREAD, eliminating the pending exception check. It may happen to work because the callee may do the check, but it requires the programmer to know that, and violates encapsulation besides. That patch and any similar ones should be revisited.