From 91c82aec24eb36cb8d760c8b0c165b08443de689 Mon Sep 17 00:00:00 2001
From: Frederic Koehler <f.koehler427@gmail.com>
Date: Sat, 11 Aug 2012 17:15:39 -0400
Subject: [PATCH 1/2] tttrace: Fix bad usage of va_arg with enums

Enums may be represented with a smaller type than int; however, they are
automatically promoted to int when passed in va_arg lists, just as
short, char, etc. are. GCC thus "knows" that you never want to call
va_arg with an enum type, and instead inserts an abort.
---
 cde/lib/tt/lib/util/tt_trace.C | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/cde/lib/tt/lib/util/tt_trace.C b/cde/lib/tt/lib/util/tt_trace.C
index 6a3d1eb..2fb9c04 100644
--- a/cde/lib/tt/lib/util/tt_trace.C
+++ b/cde/lib/tt/lib/util/tt_trace.C
@@ -384,57 +384,64 @@ _Tt_trace::entry(
 	while (num_args--) {
 		c = *preview++;
 		switch (c) {
+                        /* For the "type" to va_arg, we must pass int!
+                         * If we try to use the real type (e.g. Tt_address, etc.)
+                         * gcc will complain loudly and cause the program to abort here.
+                         * This is because the size of enums can be less than that of int,
+                         * and in va_args anything smaller than an int is "promoted"
+                         * into an int.
+                         */
 			case ADDRESS : {
 				Tt_address s;
-				s = va_arg(ap, Tt_address);
+				s = (Tt_address) va_arg(ap, int);
 				**_pstream << _tt_enumname(s);
 			} break;
 
 			case STATE: {
 				Tt_state s;
-				s = va_arg(ap, Tt_state);
+				s = (Tt_state) va_arg(ap, int);
 				**_pstream << _tt_enumname(s);
 			} break;
 
 			case DISPOSITION: {
 				Tt_disposition s;
-				s = va_arg(ap, Tt_disposition);
+				s = (Tt_disposition) va_arg(ap, int);
 				**_pstream << _tt_enumname(s);
 			} break;
 
 			case CLASS: {
 				Tt_class s;
-				s = va_arg(ap, Tt_class);
+				s = (Tt_class) va_arg(ap, int);
 				**_pstream << _tt_enumname(s);
 			} break;
 
 			case MODE: {
 				Tt_mode s;
-				s = va_arg(ap, Tt_mode);
+				s = (Tt_mode) va_arg(ap, int);
 				**_pstream << _tt_enumname(s);
 			} break;
 
 			case CATEGORY: {
 				Tt_category s;
-				s = va_arg(ap, Tt_category);
+				s = (Tt_category) va_arg(ap, int);
 				**_pstream << _tt_enumname(s);
 			} break;
 
 			case SCOPE: {
 				Tt_scope s;
-				s = va_arg(ap, Tt_scope);
+				s = (Tt_scope) va_arg(ap, int);
 				**_pstream << _tt_enumname(s);
 			} break;
 
 		        case FEATURE: {
 				Tt_feature f;
-				f = va_arg(ap, Tt_feature);
+				f = (Tt_feature) va_arg(ap, int);
 				**_pstream << _tt_enumname(f);
 			} break;
 
 			case AUDIT_STATUS: {
 				Tt_status status;
-				status = va_arg(ap, Tt_status);
+				status = (Tt_status) va_arg(ap, int);
 				**_pstream << status;
 			} break;
 
-- 
1.7.11.2

