/*----------------------------------------------------------------------* * Bounds Checking for GCC. * * Copyright (C) 1995 Richard W.M. Jones . * *----------------------------------------------------------------------* * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *----------------------------------------------------------------------* * File: * run-includes/unchecked.h * Summary: * Macros to allow per-pointer and per-use unchecked pointers. * Other notes: * * Author Date Notes * RWMJ 23/1/95 Initial implementation. * RWMJ 17/6/95 Added miscellaneous features. *----------------------------------------------------------------------*/ #ifndef _bounds_unchecked_h #define _bounds_unchecked_h #if defined(__GNUC__) && defined(__BOUNDS_CHECKING_ON) /* Make pointer operations unchecked on each use. */ #define UNCHECKED_PTR_DIFF(p,q) ((ptrdiff_t)(((unsigned)(p))-((unsigned)(q))/sizeof (*p))) #define UNCHECKED_PTR_PLUS_INT(p,i) ((typeof(p))((unsigned)(p))+(i)*(sizeof *p)) #define UNCHECKED_PTR_MINUS_INT(p,i) ((typeof(p))((unsigned)(p))-(i)*(sizeof *p)) /* How to switch checking off over a region of the program. You will need * 'DEBUG_FEATURES' set in the library. You do: * .. * BOUNDS_CHECKING_OFF; * .. strange pointer operations here .. * BOUNDS_CHECKING_ON; */ #define BOUNDS_CHECKING_OFF do {extern int __bounds_debug_no_checking; \ __bounds_debug_no_checking = 1;} while(0) #define BOUNDS_CHECKING_ON do {extern int __bounds_debug_no_checking; \ __bounds_debug_no_checking = 0;} while(0) /* Switch bounds checking off in a single statement. You do: * BOUNDS_CHECKING_OFF_DURING (stmt); * This works for most 'ordinary' statements, ie. not returns, or gotos, etc. * For expressions, use: * BOUNDS_CHECKING_OFF_IN_EXPR (expr) */ #define BOUNDS_CHECKING_OFF_DURING(stmt) \ do { extern int __bounds_debug_no_checking; \ __bounds_debug_no_checking = 1; \ stmt; \ __bounds_debug_no_checking = 0; \ } while (0) #define BOUNDS_CHECKING_OFF_IN_EXPR(expr) \ ({ extern int __bounds_debug_no_checking; \ typeof(expr) __value; \ __bounds_debug_no_checking = 1; \ __value = (expr); \ __bounds_debug_no_checking = 0; \ __value; }) #else /* not __GNUC__ or not __BOUNDS_CHECKING_ON */ #define UNCHECKED_PTR_DIFF(p,q) ((p)-(q)) #define UNCHECKED_PTR_PLUS_INT(p,i) ((p)+(i)) #define UNCHECKED_PTR_MINUS_INT(p,i) ((p)-(i)) #define BOUNDS_CHECKING_OFF #define BOUNDS_CHECKING_ON #define BOUNDS_CHECKING_OFF_DURING(stmt) stmt #define BOUNDS_CHECKING_OFF_IN_EXPR(expr) expr #endif /* __GNUC__, __BOUNDS_CHECKING_ON */ #endif /* _bounds_unchecked_h */